Restrict delegated OAuth tokens to scoped messaging - #47
Merged
Merged
Conversation
FMSG_JWT_OAUTH_AUDIENCE adds a delegated token class identified by audience alone. Delegated tokens need fmsg:read/fmsg:write for message, attachment and WebSocket routes and are refused every other route, including sub-account (API key and grant) administration. Missing or malformed scopes are refused rather than treated as an owner session, X-FMSG-Act-As is limited to identities named in the token and still subject to the grant check, and WebSocket connections end when a delegated token expires. Owner sessions and API-key tokens are unchanged, and behaviour is unchanged while the variable is unset. docs/oauth-claims.md is the claims contract for issuers and resource servers. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a delegated OAuth token class so an identity provider can issue tokens to third-party clients (for example through an MCP server using RFC 8693 token exchange) that message as the consenting user without the privileges of that user's own session. Today every provider token is an owner session, so such a token could create API keys that outlive the consent that produced it.
FMSG_JWT_OAUTH_AUDIENCEenables it. Theaudclaim alone decides the kind of token:FMSG_JWT_AUDIENCEis an owner session (unchanged),FMSG_JWT_OAUTH_AUDIENCEis delegated. Both audiences, or an owner-audience token carryingact, is rejected. Startup fails if the OAuth audience is set without a differentFMSG_JWT_AUDIENCE.fmsg:read/fmsg:writefor message, attachment and WebSocket routes and are refused every other route, including all sub-account (API key and grant) routes and push subscriptions. Routes are closed by default.scopeis refused with 403; it never falls back to owner privileges.X-FMSG-Act-Asis refused for delegated tokens unless the address is in the token'sfmsg_identitiesclaim and also passes the existing grant check.Claims contract for issuers and resource servers such as an MCP server:
docs/oauth-claims.mdTests
oauth; read-only tokens cannot write.scopeshapes are refused on both a message route and an admin route.acton the owner audience are rejected; delegated tokens are rejected while the feature is off.scopeclaim) keep administration and act-as; existing owner and API-key tests pass unchanged.registerRoutes; a test requires every route to be classified as scoped or deliberately closed.go build ./...,go vet ./...andgo test ./...pass.🤖 Generated with Claude Code