Skip to content

RFC Compliance

Authgent implements every RFC required by the MCP authorization specification. This page details exactly what is implemented, how, and where each requirement maps to.

RFCTitleStatusNotes
RFC 6749OAuth 2.0 Authorization FrameworkFullAuthorization Code grant. Client Credentials grant.
RFC 7636PKCEFullRequired for all Authorization Code flows. S256 only.
RFC 7591Dynamic Client RegistrationFullOpen or constrained mode. Metadata validation.
RFC 7009Token RevocationFullAccess and refresh token revocation.
RFC 8414OAuth AS MetadataFull/.well-known/oauth-authorization-server discovery.
RFC 9728Protected Resource MetadataFull/.well-known/oauth-protected-resource for MCP servers.
RFC 9068JWT Profile for Access TokensFullES256-signed JWTs with standard claims.
RFC 7517JSON Web Key (JWK)FullJWKS endpoint with key rotation.

RFC 6749 — OAuth 2.0 Authorization Framework

Section titled “RFC 6749 — OAuth 2.0 Authorization Framework”

Authgent implements the OAuth 2.0 framework as the foundation for all authorization flows.

Supported grant types:

  • Authorization Code (authorization_code) — Used by interactive MCP clients (Claude, Cursor, GPT). Always requires PKCE.
  • Client Credentials (client_credentials) — Used for machine-to-machine MCP server access.
  • Refresh Token (refresh_token) — Token renewal without re-authorization. Configurable expiry.

Endpoints:

EndpointPathDescription
Authorization/oauth/authorizeUser-facing consent flow
Token/oauth/tokenToken issuance and refresh
Revocation/oauth/revokeToken revocation (RFC 7009)
Registration/oauth/registerDynamic client registration (RFC 7591)

Security measures:

  • state parameter validated on all authorization responses
  • Redirect URI exact-match validation (no wildcard matching)
  • Authorization codes are single-use with 10-minute expiry
  • Refresh token rotation on every use (previous token invalidated)

RFC 7636 — Proof Key for Code Exchange (PKCE)

Section titled “RFC 7636 — Proof Key for Code Exchange (PKCE)”

PKCE is mandatory for all Authorization Code flows. Authgent does not allow Authorization Code grants without PKCE.

  • Supported method: S256 (SHA-256 hash of code verifier)
  • Rejected: plain method is not supported — Authgent returns an error if a client requests plain
  • Code verifier length: 43–128 characters per spec
  • code_challenge and code_challenge_method are required parameters on /oauth/authorize

This ensures that even if an authorization code is intercepted, it cannot be exchanged without the original code verifier.

RFC 7591 — Dynamic Client Registration (DCR)

Section titled “RFC 7591 — Dynamic Client Registration (DCR)”

MCP clients register themselves automatically — no manual client setup required.

Endpoint: POST /oauth/register

Supported client metadata:

  • redirect_uris — Required. Array of allowed redirect URIs.
  • client_name — Human-readable name shown on consent screen.
  • grant_types — Defaults to ["authorization_code"].
  • response_types — Defaults to ["code"].
  • token_endpoint_auth_methodnone for public clients, client_secret_post for confidential.
  • scope — Requested scopes (validated against server policy).

Operating modes:

ModeDescriptionUse case
OpenAny client can registerDevelopment, internal tools
ConstrainedRegistration requires a pre-shared tokenProduction, regulated deployments

Constrained mode is recommended for production. Set DCR_MODE=constrained and provide registration tokens to approved clients.

Endpoint: POST /oauth/revoke

  • Accepts both access tokens and refresh tokens via the token parameter
  • Optional token_type_hint parameter (access_token or refresh_token)
  • Always returns 200 OK regardless of whether the token existed (per spec, to prevent token enumeration)
  • Revoking a refresh token also revokes all associated access tokens

RFC 8414 — OAuth Authorization Server Metadata

Section titled “RFC 8414 — OAuth Authorization Server Metadata”

Endpoint: GET /.well-known/oauth-authorization-server

Returns a JSON document describing the authorization server’s capabilities. MCP clients use this for automatic discovery — no manual configuration needed.

Published metadata includes:

{
"issuer": "https://auth.yourcompany.com",
"authorization_endpoint": "https://auth.yourcompany.com/oauth/authorize",
"token_endpoint": "https://auth.yourcompany.com/oauth/token",
"registration_endpoint": "https://auth.yourcompany.com/oauth/register",
"revocation_endpoint": "https://auth.yourcompany.com/oauth/revoke",
"jwks_uri": "https://auth.yourcompany.com/.well-known/jwks.json",
"response_types_supported": ["code"],
"grant_types_supported": [
"authorization_code",
"client_credentials",
"refresh_token"
],
"code_challenge_methods_supported": ["S256"],
"token_endpoint_auth_methods_supported": [
"none",
"client_secret_post"
],
"scopes_supported": ["openid", "mcp:read", "mcp:write", "mcp:admin"]
}

Endpoint: GET /.well-known/oauth-protected-resource

This is the MCP-specific discovery mechanism. Your MCP server publishes this metadata so clients know which authorization server to use.

Published metadata:

{
"resource": "https://mcp.yourcompany.com",
"authorization_servers": ["https://auth.yourcompany.com"],
"scopes_supported": ["mcp:read", "mcp:write"],
"bearer_methods_supported": ["header"]
}

Authgent can serve this endpoint on behalf of your MCP server, or your MCP server can serve it directly.

RFC 9068 — JWT Profile for Access Tokens

Section titled “RFC 9068 — JWT Profile for Access Tokens”

All access tokens are signed JWTs with standard claims:

{
"iss": "https://auth.yourcompany.com",
"sub": "user_abc123",
"aud": "https://mcp.yourcompany.com",
"exp": 1700000000,
"iat": 1699996400,
"jti": "tok_unique_id",
"scope": "mcp:read mcp:write",
"client_id": "dyn_client_xyz"
}

Signing algorithm: ES256 (ECDSA with P-256 curve and SHA-256)

Why ES256?

  • Asymmetric — your MCP server verifies tokens without needing the signing key
  • Compact signatures (64 bytes vs 256 bytes for RS256)
  • Widely supported across all JWT libraries

Token lifetimes (configurable):

Token typeDefaultConfiguration
Access token1 hourACCESS_TOKEN_TTL
Refresh token30 daysREFRESH_TOKEN_TTL
Authorization code10 minNot configurable

Endpoint: GET /.well-known/jwks.json

Publishes the public keys used to verify JWT signatures. Your MCP server fetches this once, caches it, and verifies tokens offline.

{
"keys": [
{
"kty": "EC",
"crv": "P-256",
"kid": "authgent-2025-01",
"use": "sig",
"alg": "ES256",
"x": "...",
"y": "..."
}
]
}

Key rotation:

  • Authgent supports multiple active keys in the JWKS
  • New keys are added before old keys are retired (overlap period)
  • kid (Key ID) in the JWT header identifies which key to use
  • Recommended rotation interval: 90 days (configurable via KEY_ROTATION_DAYS)

The complete flow combining all RFCs:

  1. Discovery — MCP client fetches /.well-known/oauth-protected-resource from your MCP server (RFC 9728)
  2. AS Metadata — Client fetches /.well-known/oauth-authorization-server from Authgent (RFC 8414)
  3. Registration — Client registers via /oauth/register if not already registered (RFC 7591)
  4. Authorization — Client redirects user to /oauth/authorize with PKCE challenge (RFC 6749 + RFC 7636)
  5. Consent — User authenticates (optionally via upstream IdP) and approves scopes
  6. Token Exchange — Client exchanges authorization code + code verifier for tokens at /oauth/token
  7. API Access — Client sends JWT access token to your MCP server
  8. Verification — Your MCP server validates the JWT using JWKS (RFC 9068 + RFC 7517)
  9. Refresh — When the access token expires, client uses refresh token to get a new one
  10. Revocation — Client or server can revoke tokens via /oauth/revoke (RFC 7009)

Authgent includes a built-in compliance test suite you can run against your deployment:

Terminal window
# Run the full RFC compliance test suite
authgent test --target https://auth.yourcompany.com
# Test specific RFCs
authgent test --rfc 7636 --target https://auth.yourcompany.com
authgent test --rfc 7591 --target https://auth.yourcompany.com
# Verbose output with request/response logs
authgent test --target https://auth.yourcompany.com --verbose