Api.Airforce
OAUTH-PROVIDER

Inloggen met Airforce

Laat je gebruikers je app autoriseren om toegang te krijgen tot hun Api.Airforce-account. Standaard OAuth 2.0 Authorization Code flow met PKCE.

Voor wie is dit

Je bouwt een app (playground, agent, mobile client, …) en wilt dat je gebruikers hun Airforce-account koppelen zodat ze chat of beeldgeneratie via jouw UI kunnen draaien zonder hun rauwe API-key met je te delen. Gebruik deze flow.

Je krijgt een opake access_token (24h TTL) beperkt tot wat je app heeft aangevraagd en de gebruiker heeft goedgekeurd. Gebruik het als Bearer-header tegen de /v1/* -endpoints of /oauth/userinfo.

1. Een client_id + client_secret krijgen

Fase 1 is een admin-beheerde registratie. Schrijf ons aan met:

  • App-naam (getoond op het consent-scherm aan je gebruikers)
  • Beschrijving in één zin
  • Homepage-URL (optioneel, getoond bij consent)
  • Vierkante logo-URL (optioneel)
  • Een of meer exacte redirect_uri's (alleen https://, behalve http://localhost voor dev)
  • Welke scopes je nodig hebt (zie hieronder)

We sturen je client_id en een eenmalige client_secret. Bewaar het secret server-side — als je een pure SPA / native app zonder backend bent, kun je het secret overslaan en alleen op PKCE vertrouwen.

2. Scopes

ScopeWat hij verleent
profileLeest het user-object via /oauth/userinfo (id, username, plan, gekoppelde emails wanneer geverifieerd).
chatPOST /v1/chat/completions, /v1/messages, /v1/messages/count_tokens, /v1/responses.
imagesPOST /v1/images/generations.
keys:readGereserveerd — lijst de Airforce API-keys van de gebruiker (Phase 2).
keys:write (GEVOELIG)Gereserveerd — maakt + trekt de Airforce API-keys van de gebruiker in (Phase 2). Gevoelige scope.

Meerdere scopes worden gescheiden door spaties in de query-parameter scope : scope=profile chat images.

3. De flow

3.1 PKCE-paar genereren

In je client, voor je doorstuurt naar /oauth/authorize, genereer een willekeurige verifier en de bijbehorende SHA-256-challenge.

// In your app, before redirecting to /oauth/authorize:
const verifier = randomString(64); // 43..128 chars [A-Z][a-z][0-9]-._~
const challenge = base64UrlNoPad(sha256(verifier));
sessionStorage.setItem('airforce_pkce_verifier', verifier);

3.2 Doorsturen naar /oauth/authorize

Bouw de authorize-URL en stuur de gebruiker daarheen. Hij ziet ons consent-scherm, beslist, en wordt teruggestuurd naar jou.

https://api.airforce/oauth/authorize?
  response_type=code
  &client_id=airforce_xxxxxxxxxxxxxxxxxxxxxxxxx
  &redirect_uri=https://your.app/oauth/callback
  &scope=profile chat
  &state=<random opaque>
  &code_challenge=<base64url(sha256(verifier))>
  &code_challenge_method=S256

De gebruiker komt op ons consent-scherm, logt in (als nog niet gedaan), en keurt goed of weigert. We sturen terug naar je redirect_uri met een kortlopende ?code=… bij goedkeuring, ?error=access_denied bij weigering. Je oorspronkelijke state wordt teruggegeven — controleer dat het overeenkomt.

3.3 Code inwisselen voor access_token

Vanuit je backend, wissel de code (plus de PKCE-verifier) in voor een access token.

curl -X POST https://api.airforce/oauth/token \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -u "$CLIENT_ID:$CLIENT_SECRET" \
  --data-urlencode "grant_type=authorization_code" \
  --data-urlencode "code=$CODE" \
  --data-urlencode "redirect_uri=https://your.app/oauth/callback" \
  --data-urlencode "code_verifier=$VERIFIER"

Response (24h TTL):

{
  "access_token": "airf_oat_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
  "token_type": "Bearer",
  "expires_in": 86400,
  "scope": "profile chat"
}

3.4 Het token gebruiken

Roep de userinfo-endpoint aan of elke /v1/*-route die de toegekende scopes toestaan:

# Profile lookup
curl https://api.airforce/oauth/userinfo \
  -H "Authorization: Bearer $ACCESS_TOKEN"

# Chat (requires scope=chat)
curl https://api.airforce/v1/chat/completions \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"model":"gpt-4o-mini","messages":[{"role":"user","content":"Hi"}]}'

/oauth/userinfo-response

{
  "id": "user-uuid",
  "username": "foo",
  "plan": "free",
  "is_admin": false,
  "email": "[email protected]",
  "email_verified": true,
  "github_email": "[email protected]",
  "discord_username": "foo#1234"
}

Velden zoals email, github_email, discord_username verschijnen alleen wanneer de gebruiker ze echt heeft geverifieerd / gekoppeld. Plan voor zowel aanwezigheid als afwezigheid.

Een token intrekken

Wanneer een gebruiker uitlogt uit je app, trek het token in zodat het zijn account niet op de achtergrond blijft belasten:

curl -X POST https://api.airforce/oauth/revoke \
  --data-urlencode "token=$ACCESS_TOKEN"

RFC 7009. Geeft altijd 200 terug, ongeacht of het token bestond (geen oracle).

Beveiligingsopmerkingen

  • PKCE is verplicht voor publieke clients (geen server-side client_secret). We accepteren alleen S256 — code_challenge_method=plain wordt afgewezen.
  • redirect_uri is exact-match. Geen prefix / wildcard matching. Als je meerdere omgevingen nodig hebt, registreer één URI per omgeving.
  • Tokens hebben een TTL van 24u en nog geen refresh tokens — bij expiratie, stuur de gebruiker opnieuw door /oauth/authorize . Voor langlopende agents, vraag bij opstart en bewaar het token in veilige opslag.
  • Bewaar client_secret niet in client-side code. Als je app een browser-only SPA of native client is, registreer zonder server en vertrouw op PKCE.
  • Gebruikers kunnen je app op elk moment intrekken vanuit hun dashboard → Apps-tab. Handel 401 af door de OAuth-flow opnieuw te starten.
  • Phase 1-dekking: OAuth-bearer-tokens werken op /v1/chat/completions, /v1/messages, /v1/messages/count_tokens, /v1/responses, /v1/images/generations, en /oauth/userinfo. Audio-, video-, voice- en character-endpoints vereisen in Phase 1 nog steeds een reguliere Airforce API-key.

Registreren

Email naar [email protected] of bereik ons op Discord met de registratiedetails hierboven. Je krijgt je credentials binnen een paar uur terug.

Vastgelopen bij het instellen of wil je een gratis sleutel? Vraag het de community op onze Discord.

Word lid van onze Discord