API Reference
The authserver binary exposes two HTTP servers:
- Public (default
:9000) — OAuth 2.1 endpoints, MCP discovery, RFC-compliant well-known documents, the consent + login UI, and the connect/disconnect surface for broker-vended upstream providers. - Admin (default
:9001) — provisioning and day-2 operations, protected byAuthorization: Bearer <AUTHPLANE_ADMIN_API_KEY>. The/metricsendpoint lives on the admin server, gated by Prometheus basic auth. This port must never be reachable from the internet.
This page is the orientation map. The full per-endpoint reference (request/response DTOs, status codes, source locations) is generated directly from route registrations in the authserver repo — linked at the bottom.
Public endpoints (:9000)
Section titled “Public endpoints (:9000)”| Method | Path | Auth | Purpose |
|---|---|---|---|
GET | /.well-known/oauth-authorization-server | None | RFC 8414 authorization server metadata — the discovery document MCP clients fetch first. |
GET | /.well-known/openid-configuration | None | OIDC-style discovery alias; returns the same document as the RFC 8414 endpoint. |
GET | /.well-known/jwks.json | None | JWKS document (public keys only) for offline JWT verification. Served with Cache-Control: max-age=300. |
GET | /oauth/authorize | Browser session | Starts the authorization code flow. Query parameters per RFC 6749 §4.1.1 plus PKCE (code_challenge, code_challenge_method=S256). Redirects to /consent after login. |
POST | /oauth/token | Client auth via request parameters (none for public clients) | Token issuance for all five grant types: authorization_code, refresh_token, client_credentials, token exchange, and JWT bearer (XAA). DPoP-bound clients send a DPoP header; the AS may challenge with WWW-Authenticate: DPoP error="use_dpop_nonce". |
POST | /oauth/revoke | None (token identifies the caller) | RFC 7009 revocation. Form-encoded token + token_type_hint; always returns 200 with an empty body. |
POST | /oauth/introspect | Client auth required for confidential clients | RFC 7662 introspection for access and machine tokens. Returns cnf.jkt for DPoP-bound tokens. |
POST | /oauth/register | None (gated by DCR mode) | RFC 7591 dynamic client registration. Accepts client metadata JSON, returns 201 with the registered client. Behavior depends on the DCR mode: open, approved_redirects, or admin_only. |
GET | /connect/{provider} | Browser session | Starts the upstream provider connect flow for broker-vended tokens; the provider redirects back to /connect/{provider}/callback. |
The public server also serves the browser surface (/login, /consent, /connections, /oidc/start, /oidc/callback) and the operational probes /health and /ready.
Admin API (:9001)
Section titled “Admin API (:9001)”Every admin route requires Authorization: Bearer <AUTHPLANE_ADMIN_API_KEY>, and every admin action is audit-logged. Grouped by noun:
| Area | Endpoints | What it manages |
|---|---|---|
| Clients | /admin/clients, /admin/clients/{id}, plus /suspend, /reactivate, /revoke, /rotate-secret | OAuth client CRUD and lifecycle: suspend or reactivate a client, revoke it, rotate its secret. |
| Users | /admin/users, /admin/users/{id}, plus /enable, /disable, /{id}/grants, /{id}/tokens | User CRUD, enable/disable, per-user grant listing, and per-user token listing/revocation. |
| Resources | /admin/resources, /admin/resources/{id}, /admin/resources/{slug}/fronting, /admin/resources/{slug}/policy/… | The protected-resource registry and per-resource policy: connect/allowed-return-urls, exchange/allowed-clients, and runtime/client-ids. |
| Broker providers | /admin/broker-providers, /admin/broker-providers/{id} | Upstream provider registry for the token broker (GitHub, Google, Slack, …). |
| Grants | /admin/grants/consent/{id}, /admin/grants/broker/{id} | Revoke individual consent grants and broker grants. |
| Audit | /admin/audit | Query the audit log (filterable, e.g. by client_id). |
| Keys | /admin/keys, /admin/keys/rotate | List signing keys and rotate them online. |
| Fronting | /admin/fronting, /admin/fronting/{source}/{target} | Fronting links between resources (scope mapping across resource namespaces). |
| IdPs & XAA | /admin/idps, /admin/idps/{id}, /admin/idps/{id}/refresh-keys, /admin/xaa/policies, /admin/xaa/subject-mappings | Trusted IdP registry for enterprise-managed authorization, XAA policies, and subject mappings. |
| Issuances | /admin/issuances, /admin/issuances/{id} | The forensic record of vended tokens: who acted, for which user, on which resource, with which scopes. |
| Tokens | /admin/tokens, /admin/tokens/{jti} | Active token listing and revocation by JTI. |
| Settings & ops | /admin/settings/dcr, /admin/stats, /admin/system/config, /admin/system/status, /admin/auth/verify, /metrics | Runtime DCR settings, instance stats, effective config, status, API-key verification, and Prometheus metrics. |
Each admin endpoint has a matching authserver admin … CLI subcommand that round-trips the same wire shapes.
Error format
Section titled “Error format”Every error response combines OAuth 2.0 error codes (RFC 6749) with RFC 9457 Problem Details, served as Content-Type: application/problem+json:
{ "error": "invalid_grant", "error_description": "the authorization grant is invalid, expired, or revoked", "type": "https://docs.authplane.ai/errors/invalid_grant", "title": "Bad Request", "detail": "the authorization grant is invalid, expired, or revoked", "status": 400}The error field is the machine-readable code your client should switch on; error_description explains what happened. Two errors carry extra structure:
use_dpop_nonce— retryable immediately: read theDPoP-Nonceresponse header, add it to your proof, and retry.consent_required(token exchange) — includes aconsent_urlto send the user to and acausefield (consent_missingorscope_insufficient):
{ "error": "consent_required", "error_description": "Authorize access to google-calendar", "consent_url": "https://as.example.com/connect/google-calendar", "cause": "consent_missing", "type": "https://docs.authplane.ai/errors/consent_required", "title": "Bad Request", "detail": "Authorize access to google-calendar", "status": 400}Which errors to retry
Section titled “Which errors to retry”| Error | Retry? | What to do |
|---|---|---|
use_dpop_nonce | Yes — immediately | Read the DPoP-Nonce header, update the proof, retry. |
slow_down (429) | Yes — after delay | Wait for the Retry-After duration. |
server_error (500) | Yes — with backoff | Exponential backoff; if persistent, check server logs. |
invalid_grant | No | The grant is consumed or expired. Start a fresh flow. |
invalid_client, invalid_scope, unauthorized_client, access_denied | No | Fix the credentials, scopes, registration, or policy. |
Admin API errors use plain HTTP semantics: 401 missing/invalid API key, 400 bad request body, 404 not found, 409 conflict (e.g. duplicate resource slug), 429 rate limited, 500 server error.