Skip to content

P12: gateway MCP-scope enforcement #69

Description

@ehsan6sha

P12 — Gateway MCP-scope enforcement

The S3 gateway (crates/fula-cli) must PARSE and ENFORCE the scoped MCP-S3 JWT minted by the pinning-webui (P11/P11.1). The claim shape is a cross-service contract (reference verifier: pinning-service-mcp/pinning-webui/server/mcpTokens.ts::verifyMcpToken).

Token shape

HS256 JWT (shared JWT_SECRET); payload carries token_use:mcp_s3, 64-hex sub, iss/aud/exp/nbf/jti, and:

mcp: { v:1, scopes:[ { bucket:fula-ai-workspace, prefix:ai/, perms:[read,write,list] } ] }

Long-lived storage JWTs share the secret but carry scope:storage:* and NONE of token_use/mcp/exp/typ.

What the gateway must do

  • Detect MCP via the token_use claim (the decoder discards the JOSE header).
  • Fail-closed: a token flagged token_use:mcp_s3 but with a missing/invalid/v!=1 mcp claim is REFUSED — it must never fall through to broad storage access. (Hardening: a token carrying mcp WITHOUT token_use:mcp_s3 is also refused as ambiguous.)
  • Fence the MCP token to its single bucket + ai/ prefix + perms on every S3 data operation; unknown perm strings are ignored (forward-compat, never a grant).
  • Normal storage tokens must behave byte-identically (no scope ⇒ enforcement is a no-op).
  • Cross-user isolation is unchanged (already from (hashed_user_id, bucket) + JWT sub); P12 adds the intra-user bucket/prefix/perm fence.

Revocation seam (jti)

An MCP jti deny-list (sibling of the existing key revocation), env-gated and mockable; fail-CLOSED on write when the source is enabled-but-unreachable, open on read. Live HTTP polling defaults OFF (deferred to the test-server deploy). Scope enforcement is the must-have.

Out of scope for P12 (noted)

typ/iss/aud/nbf enforcement is deferred (the decoder already pins HS256 so none fails; exp is covered; token_use+mcp.v defeat token-confusion).

Tracked-in: branch p12-gateway-scope → PR into feat/fula-mcp.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions