Protocol reference
These pages describe what happens on the wire when each flow runs: the OAuth server's endpoints, the requests callers send, the responses and errors they receive, and the tokens Defakto issues. Each flow follows a public standard. These pages link to the standards and describe Defakto's choices and values, rather than repeating the standards.
For step-by-step guides, see the scenarios. For the configuration, see OAuthServer configuration.
| Page | Covers |
|---|---|
| Token requests | The parameters, responses, and errors for each flow, and how callers authenticate |
| Tokens | What each token contains, how to validate it, and how long it lives |
| DPoP | Binding access tokens to a key the caller holds |
Flows
| Flow | Standard | Caller | Presents | Receives |
|---|---|---|---|---|
| Workload access token | JWT bearer grant (RFC 7523) | A workload | Its JWT-SVID | An access token |
| User sign-in | Authorization code grant with PKCE | An OAuth client | A person's sign-in | An access token for the person |
| On-behalf-of token | Token exchange (RFC 8693) | A workload | A user's ID token or access token, or an on-behalf-of token | An on-behalf-of token |
| Transaction Token | Token exchange, and the Transaction Tokens draft | A workload | A user's ID token or access token | A Transaction Token |
| External service token | Token exchange | A workload | Nothing beyond its own identity | The external service's access token |
Endpoints
The OAuth server runs in your Trust Domain Servers. Its endpoints are at the address in endpoints.publicBaseURL:
| Endpoint | Used for |
|---|---|
<publicBaseURL>/oauth/token | Every flow's token request |
<publicBaseURL>/oauth/authorize | Starting the authorization code flow. An OAuth client sends the person's browser here. |
<publicBaseURL>/oauth/upstream-callback | Finishing a user sign-in. Your identity provider sends the browser back here. |
The token endpoint accepts POST requests with a form-encoded body of at most 32 KiB.
Issuers and discovery
The OAuth server has its own issuer, the OAuth issuer, separate from the trust domain's JWT-SVID issuer. Defakto publishes discovery documents for the OAuth issuer. Find their URLs in the Defakto console, under your trust domain's Settings > Trust domain URLs, or in the output of defakto trust-domain info <trust-domain>:
| Name in the console and CLI | What it is |
|---|---|
| OAuth Issuer | The OAuth issuer, which appears as iss in the tokens the OAuth server issues. MCP servers list it as their authorization server. |
| OAuth Authorization Server Metadata | The RFC 8414 metadata document. It lists the authorization_endpoint and token_endpoint at your publicBaseURL, the JWKS, the accepted DPoP signing algorithms, and the supported PKCE methods. After a configuration change, it can take up to an hour to update. |
| OAuth OIDC Discovery Endpoint | The OpenID Connect discovery document for the OAuth issuer |
| OAuth JWKS Endpoint | The keys that verify the tokens the OAuth server issues |
To get the OAuth issuer from the CLI:
defakto trust-domain info <trust-domain> --output json | jq -r '.oauth_issuer.issuer'
Signing keys
The OAuth server signs access tokens and Transaction Tokens with the trust domain's OAuth signing key, which is separate from its JWT-SVID signing key. On-behalf-of tokens are JWT-SVIDs, so they're signed with the JWT-SVID signing key:
| Token | Verify with |
|---|---|
| Access token | The OAuth JWKS Endpoint |
| Transaction Token | The OAuth JWKS Endpoint |
| On-behalf-of token | The trust domain's JWT-SVID keys, as for any JWT-SVID |
The OAuth signing key is part of each Trust Domain Server deployment's signing key set, and rotates with it. By default, it's an RSA 4096-bit key. To use a different key type, see signing key policy.