OAuth 2.0
Authorization Code with PKCE for public clients; authorize in the browser, exchange the code at `/api/oauth/token`, call `/api/v1` with the access token.
Third-party and official clients use OAuth 2.0 Authorization Code + PKCE. Confidential clients with a client_secret are supported for server-side apps registered by workspace owners.
Public client flow (Lightroom)
1. Plugin opens browser → GET /oauth/authorize?client_id=…&code_challenge=…&redirect_uri=…&scope=…
2. User logs in (if needed) → consent screen (scopes + workspace)
3. Redirect to loopback → ?code=…
4. POST /api/oauth/token (code + code_verifier) → access + refresh tokens
5. API calls → Authorization: Bearer aist_at_…
Desktop clients use a loopback redirect (e.g. http://127.0.0.1:54321/callback) registered on the OAuth application. Public clients do not embed a client_secret.
Endpoints
| Method | Path | Role |
|---|---|---|
| GET | /oauth/authorize | Consent page (reuses dashboard login when needed) |
| POST | /api/oauth/token | Exchange code or refresh token |
| POST | /api/oauth/revoke | Revoke access or refresh token |
Platform vs custom clients
| Tier | Who registers | Dashboard |
|---|---|---|
| Platform | ArtInStack ops (Directus oauth_clients) | User sees app under Connected apps after consent |
| Workspace | Workspace owner | Settings → Developer → OAuth applications |
Official Lightroom uses a platform-owned client row. Photographers do not register it themselves.
Refresh
Use the refresh token at /api/oauth/token before the access token expires. Serialize refresh in the client to avoid races during concurrent uploads.
