MCP OAuth¶
The MCP server supports OAuth 2.0 authentication, allowing MCP clients to authenticate as AMSDAL users with full permission checks.
Overview¶
When OAuth is enabled, MCP clients must authenticate before accessing tools. The flow:
- Client discovers OAuth endpoints via
/.well-known/oauth-protected-resource - Client registers and receives a
client_id - User is redirected to AMSDAL's login page
- After login, client receives an authorization code
- Client exchanges code for access + refresh tokens
- Tokens are sent with each MCP request
All AMSDAL permission checks (class-level and object-level) are applied based on the authenticated user.
Configuration¶
| Env Variable | Default | Description |
|---|---|---|
OAUTH_ENABLED |
true |
Enable/disable OAuth for MCP |
OAUTH_CLIENT_ID_EXPIRATION_DAYS |
30 |
Client ID token expiration (days) |
OAUTH_CODE_EXP_MINUTES |
10 |
Authorization code expiration (minutes) |
OAUTH_ACCESS_TOKEN_EXP_HOURS |
24 |
Access token expiration (hours) |
OAUTH_REFRESH_TOKEN_EXP_DAYS |
90 |
Refresh token expiration (days) |
OAUTH_LOGIN_PATH |
/auth/login |
Custom login page path |
OAUTH_ISSUER |
http://127.0.0.1:8000 |
Token issuer identifier |
OAuth Endpoints¶
The following endpoints are mounted automatically when the plugin is registered:
| Endpoint | Method | Description |
|---|---|---|
/.well-known/oauth-protected-resource |
GET | Protected resource metadata |
/.well-known/oauth-authorization-server |
GET | Authorization server metadata |
/register |
POST | Client registration (returns client_id) |
/oauth/authorize |
GET | Authorization endpoint (redirects to login) |
/oauth/token |
POST | Token exchange (code → access/refresh tokens) |
/auth/login |
GET/POST | Login page for user authentication |
PKCE Support¶
The OAuth flow uses PKCE (Proof Key for Code Exchange) with S256 challenge method for security. MCP clients that support OAuth (like Chatbox AI) handle PKCE automatically.
Token Flow¶
Client AMSDAL Server
| |
|-- POST /register ----------->| (get client_id)
|<---- client_id --------------|
| |
|-- GET /oauth/authorize ----->| (with PKCE challenge)
|<---- redirect to login ------|
| |
| [User logs in] |
| |
|<---- authorization code -----|
| |
|-- POST /oauth/token -------->| (code + PKCE verifier)
|<---- access + refresh token -|
| |
|-- MCP request + Bearer ----->| (authenticated)
|<---- response ---------------|
Auth Bridge¶
The OAuthAuthenticateBridgeListener translates OAuth bearer tokens into internal AMSDAL auth tokens. This ensures that:
- The MCP request runs in the context of the authenticated user
- All AMSDAL permission checks apply (class-level, object-level)
- Audit trails show the actual user, not a service account
Token Refresh¶
When an access token expires, the client uses the refresh token to get a new pair:
POST /oauth/token
Content-Type: application/x-www-form-urlencoded
grant_type=refresh_token&refresh_token=<token>&client_id=<id>
Refresh tokens are rotated on each use — a new refresh token is issued. Note that old refresh tokens remain valid until their natural JWT expiry.
Disabling OAuth¶
For development or trusted environments, you can disable OAuth:
export OAUTH_ENABLED=false
Without OAuth, the MCP server is accessible without authentication. Use this only in development.