raw .md

OAuth flow

GAUTH implements the authorization-code flow for app users. There is no PKCE and no refresh token.

1. Register a redirect URI

The redirect URI must be registered on the app before the flow starts.

curl -sS -X PATCH "$MANAGE/apps/1" -H "$AUTH" \
  -H "Content-Type: application/json" \
  -d '{"redirect_uris":["https://acme.example/cb"]}'

2. Send the user to the authorize endpoint

GET /authorize?client_id=app_1a2b3c4d5e6f7a8b&redirect_uri=https%3A%2F%2Facme.example%2Fcb&response_type=code&scope=profile&state=random-string
parameterrequirednotes
client_idyesthe app's app_key
redirect_uriyesmust match a registered URI exactly
response_typeyesmust be code
scopenodefaults to profile, up to 200 characters
statenoreturned unchanged, use it to stop CSRF

If the user is not signed in, GAUTH shows the app user login form. After login it shows a consent page with the app name, the requested scope and the redirect target.

3. Handle the redirect

Allow:

https://acme.example/cb?code=...&state=random-string

Deny:

https://acme.example/cb?error=access_denied&state=random-string

Check state before using the code.

4. Exchange the code

curl -sS -X POST "$API/token" \
  -H "Content-Type: application/json" \
  -d '{
    "grant_type": "authorization_code",
    "code": "...",
    "client_id": "app_1a2b3c4d5e6f7a8b",
    "client_secret": "gsk_...",
    "redirect_uri": "https://acme.example/cb"
  }'

The response is a normal token response with scope app profile.

Code rules

  • A code is single use.
  • A code expires after the configured code TTL, 300 seconds by default.
  • A code is bound to the app and the redirect URI that created it.
  • An invalid, expired or used code returns invalid_grant.

Errors

errormeaning
unknown_appthe client_id is not an app key
app_disabledthe app is disabled
bad_redirectthe redirect URI is not registered
invalid_inputresponse_type is not code
access_deniedthe user pressed Deny

Notes

  • The consent page is served by GAUTH, not by your app.
  • The user must be an app user of the same app family. A client account cannot complete this flow.