Configuration reference¶
All commands are installed by uv sync as console scripts. --socket defaults to the SPIFFE_ENDPOINT_SOCKET environment variable.
The flag tables, fixed values and policy schema below are generated from the code by scripts/gen_config_docs.py. CI fails if they drift.
mcp-svid-authz¶
JWT-SVID to access token bridge (POC)
| Flag | Default | Meaning |
|---|---|---|
--issuer |
required | Public base URL, used as iss and as the required SVID aud; trailing slash removed |
--policy |
required | Path to the policy YAML file |
--host |
127.0.0.1 |
Listen address |
--port |
8100 |
Listen port |
--static-jwks |
none | Test mode: JWT-SVID bundle as a JWKS file instead of the Workload API |
--socket |
none | Workload API socket for JWT bundles, default SPIFFE_ENDPOINT_SOCKET |
--audit-log |
none | Audit log file (JSON lines, appended), default stderr |
--max-svid-lifetime |
300 |
Reject JWT-SVIDs whose exp - iat exceeds this many seconds |
--svid-replay |
reject |
Reject: require a JWT-SVID jti and accept each (sub, jti) once; allow-reuse-within-lifetime: jti optional, a reused SVID is accepted until it expires |
Fixed values:
| Setting | Value |
|---|---|
| Access token TTL | 300s |
| Access token algorithm | ES256 |
| SVID clock leeway | 30s |
| Trust bundle cache (Workload API) | 30s |
mcp-svid-notes¶
Notes MCP server (POC)
| Flag | Default | Meaning |
|---|---|---|
--name |
notes |
Server name, also used in the audit component (mcp_server:<name>) |
--resource |
required | Canonical URI, e.g. http://host:8101/mcp; must equal the token aud |
--issuer |
required | Authorization server issuer URL |
--jwks-uri |
none | JWKS location, default <issuer>/jwks.json |
--host |
127.0.0.1 |
Listen address |
--port |
8101 |
Listen port |
--audit-log |
none | Audit log file (JSON lines, appended), default stderr |
Fixed values:
| Setting | Value |
|---|---|
| Tools (scope) | notes.search (notes:read), notes.write (notes:write) |
| JWKS cache | 60s |
Unknown kid refetch |
at most every 10s |
| Request body limit | 1048576 bytes |
Accepted token typ |
at+jwt |
| Accepted token algorithms | ES256 |
mcp-svid-agent¶
Agent that authenticates with its JWT-SVID
| Flag | Default | Meaning |
|---|---|---|
--resource |
required | MCP server canonical URI |
--scope |
required | Space separated scopes, e.g. 'notes:read notes:write' |
--trusted-issuer |
required | Authorization server issuer the agent may mint SVIDs for; repeatable, exact match |
--spiffe-id |
none | Sent as client_id |
--socket |
none | Workload API socket, default SPIFFE_ENDPOINT_SOCKET |
--steal-token |
none | Demo: send the token issued for --resource to OTHER_RESOURCE instead |
mcp-svid-stdio¶
Run a stdio MCP server with a short-lived token from the Workload API
| Flag | Default | Meaning |
|---|---|---|
--resource |
required | Upstream resource the child calls |
--scope |
required | Space separated scopes |
--trusted-issuer |
required | Authorization server issuer the wrapper may mint SVIDs for; repeatable, exact match |
--socket |
none | Workload API socket, default SPIFFE_ENDPOINT_SOCKET |
--refresh-margin |
60 |
Seconds before expiry to refresh |
--export-token-env |
off | Also set MCP_ACCESS_TOKEN (weaker: visible in the environment, never refreshed) |
-- command [args...] |
required | Child command, after -- |
Fixed values:
| Setting | Value |
|---|---|
| Exit code when the token cannot be refreshed | 75 |
Policy file¶
Example from deploy/policy.yaml:
# Which SPIFFE IDs may get access tokens for which MCP servers, with which scopes.
# Anything not listed is denied.
trust_domain: example.org
clients:
- spiffe_id: spiffe://example.org/agent/research
resources:
http://notes-a:8101/mcp: [notes:read, notes:write]
http://notes-b:8102/mcp: [notes:read]
# spiffe://example.org/agent/intruder has a valid SVID but is deliberately not listed.
| Key | Type | Meaning |
|---|---|---|
trust_domain |
string, required | Only SVIDs from this trust domain are accepted |
clients |
list | One entry per SPIFFE ID |
clients[].spiffe_id |
string, required | Exact SPIFFE ID (SVID sub) |
clients[].resources |
map | Resource URI to list of allowed scopes. Trailing slashes are ignored when matching. |
Behaviour notes¶
mcp-svid-agentcallsnotes.searchthennotes.write. It exits with code 2 and prints atoken_deniedevent when the token request fails.mcp-svid-stdiois described in stdio wrapper.
Policy decisions¶
The policy is an allowlist of which SPIFFE IDs may get access tokens for which MCP servers, with which scopes. Anything not listed is denied.
Decision order:
| Condition | Error |
|---|---|
| SPIFFE ID not listed | unauthorized_client |
| Resource not listed for that ID | invalid_target |
| Requested scopes not a subset of the listed scopes | invalid_scope |
The token carries exactly the requested scopes, not the full grant.