Skip to main content
Every MCP server deployed on ezForge is protected by OAuth 2.1 with mandatory PKCE (Proof Key for Code Exchange). This ensures that only authorized clients — AI assistants, agents, or applications — can call your server’s tools.

Why OAuth 2.1?

The Model Context Protocol specification recommends OAuth 2.1 as the standard auth mechanism for HTTP-based MCP servers. It provides:
  • Short-lived access tokens that limit the impact of token leakage
  • Refresh tokens for long-lived sessions without re-authentication
  • Fine-grained scopes to control what clients can do
  • PKCE to prevent authorization code interception attacks (mandatory — plain method not accepted)

How it works

MCP Client (AI Assistant)

         │  1. Discover auth metadata

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

         │  2. Redirect to authorization server

auth.ezforge.ai/oauth/authorize
    ?client_id=...
    &code_challenge=<S256-hash>
    &code_challenge_method=S256
    &redirect_uri=...
    &scope=mcp:execute

         │  3. User approves (or auto-approved for trusted clients)
         │  4. Auth code returned to redirect_uri

POST auth.ezforge.ai/oauth/token
    grant_type=authorization_code
    &code=...
    &code_verifier=<original-random>
    &resource=https://my-server.mcp.ezforge.ai

         │  5. Access token issued (bound to server URI)

GET /sse
    Authorization: Bearer <access-token>

Resource Indicators (RFC 8707)

Access tokens are bound to a specific server URI using RFC 8707 Resource Indicators. A token issued for my-server.mcp.ezforge.ai cannot be used to call any other server. This prevents token replay attacks across servers.

MCP scopes

ScopeDescription
mcp:readList available tools on the server
mcp:writeCall tools that modify state
mcp:executeExecute any tool call (most permissive)
offline_accessRequest long-lived refresh tokens

ezforge_managed mode

When a server uses ezforge_managed auth (the default), ezForge acts as the OAuth authorization server:
  • ezForge registers the MCP client
  • Handles the authorization flow
  • Issues and validates tokens
  • No configuration required from you

BYOA mode (Bring Your Own Auth)

If you already run an OAuth 2.1 authorization server, you can configure your ezForge server to accept tokens from it:
ezforge servers update my-server \
  --auth-mode byoa \
  --byoa-issuer https://auth.example.com \
  --byoa-jwks-uri https://auth.example.com/.well-known/jwks.json \
  --byoa-authorization-endpoint https://auth.example.com/oauth/authorize \
  --byoa-token-endpoint https://auth.example.com/oauth/token
ezForge validates incoming tokens by:
  1. Fetching your JWKS endpoint to get public keys
  2. Verifying the JWT signature
  3. Checking the iss claim matches your configured issuer
  4. Checking the aud claim includes the server’s URI (RFC 8707)
  5. Verifying the token is not expired

Protected Resource Metadata

All ezForge-hosted servers expose the RFC 9728 standard endpoint:
GET https://{slug}.mcp.ezforge.ai/.well-known/oauth-protected-resource
{
  "resource": "https://my-server.mcp.ezforge.ai",
  "authorization_servers": ["https://auth.ezforge.ai"],
  "scopes_supported": ["mcp:read", "mcp:write", "mcp:execute", "offline_access"],
  "bearer_methods_supported": ["header"]
}
This allows MCP clients to automatically discover how to authenticate — no manual configuration needed.

Token lifetimes

TokenLifetimeNotes
Authorization code5 minutesSingle-use; consumed on token exchange
Access token15 minutesShort-lived; limits blast radius of leakage
Refresh token30 daysRotated on each use

Security recommendations

  • Request only the scopes your application needs
  • Use offline_access only when a long-lived session is necessary
  • Treat access tokens as secrets — don’t log them or include them in URLs
  • Rotate refresh tokens regularly; ezForge rotates them automatically on use