OAuth flow (detailed)
This page is the reference for anyone implementing a custom MCP client or debugging OAuth issues against K-AI. Both MCP servers (api-retrieval and api-audit) share a single Authorization Server at https://auth-api.kai-studio.ai. A token obtained against either resource server is accepted on both.
Sequence diagram
Every ~15 minutes the client refreshes the access token by calling /auth/oauth/token with grant_type=refresh_token; the response contains a new access token and a rotated refresh token.
Step-by-step
1. Discovery
GET https://api-retrieval.kai-studio.ai/.well-known/oauth-authorization-server (or the api-audit equivalent — both return identical metadata). The response contains registration_endpoint, authorization_endpoint, token_endpoint, revocation_endpoint, supported response/grant types, PKCE methods, and scopes.
2. Dynamic Client Registration (RFC 7591)
POST to /auth/oauth/register with client_name, redirect_uris, grant_types, and token_endpoint_auth_method. The server returns a fresh client_id and client_secret. K-AI Auth supports confidential clients only — every MCP client (Claude Desktop, Cursor, Le Chat) registers with a client_id + client_secret and stores the secret locally.
3. Authorization request
Generate a code_verifier (43–128 chars), derive code_challenge = BASE64URL(SHA256(code_verifier)), pick a random state, and open the user's browser at /auth/oauth/authorize with response_type=code, client_id, redirect_uri, scope=mcp, state, code_challenge, code_challenge_method=S256. The user signs in via magic code or Microsoft SSO.
4. Authorization code delivery
The Authorization Server redirects to redirect_uri?code=<code>&state=<state>. The client must verify state matches what it sent.
5. Token exchange
POST to /auth/oauth/token with grant_type=authorization_code, code, redirect_uri, client_id, and code_verifier. The server returns access_token (JWT, 15 min TTL) and refresh_token (7 days TTL).
6. Authenticated tool calls
Subsequent tool invocations go to https://api-retrieval.kai-studio.ai/mcp or https://api-audit.kai-studio.ai/mcp with the header Authorization: Bearer <access_token>.
7. Refresh
When the access token nears expiry, POST to /auth/oauth/token with grant_type=refresh_token. The server returns a new access token and a rotated refresh token. The previous refresh token is invalidated immediately.
Token verification is performed server-side by K-AI's resource APIs, not by clients. Treat the access token as an opaque bearer credential.
Spec details
PKCE:
S256required. Plaintext (plain) not accepted.Token lifetimes: access token 15 min, refresh token 7 days.
Refresh rotation: mandatory. Each refresh call returns a new refresh token and invalidates the old one immediately. If a revoked refresh token is presented again, the entire token chain is revoked and the user must re-authorize.
Authorization code TTL: 10 minutes, single-use.
Token endpoint auth methods supported:
client_secret_basic,client_secret_post. Confidential clients only — the token endpoint rejects requests without aclient_secretwithinvalid_client 401.Scope:
mcp.DCR rate limit: 5 requests per minute per IP.
Endpoints
Discovery (from either K-AI API)
https://<api>/.well-known/oauth-authorization-server
GET
Dynamic Client Registration
https://auth-api.kai-studio.ai/auth/oauth/register
POST
Authorization
https://auth-api.kai-studio.ai/auth/oauth/authorize
GET
Token exchange and refresh
https://auth-api.kai-studio.ai/auth/oauth/token
POST
Revocation
https://auth-api.kai-studio.ai/auth/oauth/revoke
POST
Both api-retrieval.kai-studio.ai and api-audit.kai-studio.ai publish their own discovery document, but both point to the same Authorization Server. Register your client once; the resulting tokens are accepted on both APIs.
Troubleshooting
401after 15 min: access token expired. Refresh it. Most MCP clients do this automatically.invalid_granton refresh: the stored refresh token is stale — an older one was used after a successful rotation. Always replace the stored refresh token with the latest one returned.CSRF / state mismatch: the
statereturned toredirect_uridoes not match what the client sent. Persiststatefor the lifetime of the flow.Microsoft SSO loop: confirm the user's browser is not blocking third-party cookies on
auth-api.kai-studio.ai.DCR rejected (
429): the rate limit of 5 registrations per minute per IP was exceeded. Wait and retry.invalid_clienton token exchange: theclient_iddoes not match the one returned by DCR, or theclient_secretis wrong or missing. K-AI Auth supports confidential clients only — every token request must carry aclient_secret.invalid_requestwithcode_verifier: thecode_verifierdoes not match thecode_challengeused at the authorization step. Regenerate both as a pair.
For the higher-level narrative on K-AI authentication, see OAuth 2.1.
Last updated