Concepts¶
MCP Runtime helps a team publish MCP servers and decide which agents can use their tools. A server describes what runs, a grant says what an agent may do, and a session records time-limited access. The gateway checks each tool call. The adapter helps an MCP client connect with the right identity.
The sections below explain the resources behind these ideas. For the full authorization model, see Identity and authorization.
The whole thing, as a building¶
If it helps, think of the platform as an office building that rents suites to tools and admits visiting agents:
| In the building | In MCP Runtime | What that means |
|---|---|---|
| A floor assigned to one company | Namespace (mcp-team-acme) |
Groups a team's servers, grants, and secrets. Kubernetes RBAC, network policy, and platform API checks enforce the boundary. |
| The signed lease describing the suite | MCPServer |
Declarative description: image, port, route, tools, policy, gateway on/off. |
| Facilities, who reads the lease and builds the room | Operator | Turns one MCPServer into a Deployment, Service, Ingress, and policy ConfigMap. |
| Lobby reception, pointing visitors to the right floor | Traefik ingress | Routes /<server>/mcp to the right Service and can verify adapter certificates. Per-tool authorization happens in the gateway. |
| The guard at the suite's own door | mcp-gateway sidecar |
Evaluates configured policy for tool calls before forwarding them to the server. |
| The standing rule in the security handbook | MCPAccessGrant |
Long-lived policy: which tools, up to what trust, with which side effects. |
| Today's visitor badge, expiring at 6pm | MCPAgentSession |
Time-bounded record of delegated identity and consent; revocation reaches gateways after policy refresh, usually within about 10 seconds. |
| Clearance printed on the badge | Trust level (low / medium / high) |
A ceiling, never a grant of power on its own. |
| "May look" vs "may edit" vs "may shred" | Side effect (read / write / destructive) |
What the tool does to data, authorized separately from trust. |
| The badge carrier who presents your certificate | Adapter | Local proxy that enrolls and refreshes a session-bound client certificate. |
| Cameras and the logbook | Audit and observability | Audit events, analytics, dashboards in mcp-observability. |
Platform trust model¶
MCP Runtime does not treat a caller as globally trusted because it has one valid credential. A request crosses three separate identity and authorization planes:
- Platform control: a user or service principal authenticates to the platform APIs. Its role, team membership, namespace scope, and resource ownership determine whether it can manage servers, grants, and sessions.
- MCP tool access: a human delegates an agent's access through a grant. The platform issues a time-bound session for an authorized agent. The adapter proves that session with a certificate; on an OAuth-enabled server, the MCP request also carries a bearer token whose subject must match the session's human. The gateway checks the identity, session, grant, tool rules, declared side effect, and trust requirement on each tool call.
- Kubernetes operations: the operator and other workloads use their own ServiceAccounts and RBAC to manage cluster resources. This authority is separate from both platform-user roles and agent access.
flowchart LR
subgraph Platform[Platform control plane]
Human[Human or service principal] -->|platform credential| APIs[Platform APIs]
APIs -->|role, team, namespace, ownership checks| Actions[Authorized control-plane actions]
Actions --> Grant[MCPAccessGrant]
Actions --> Session[MCPAgentSession]
end
subgraph Requests[MCP request path]
Client[Claude, Cursor, Codex, or another MCP client]
Adapter[Adapter proxy]
Ingress[Traefik ingress]
Gateway[mcp-gateway]
Server[MCP server]
Audit[Audit event]
Metadata[MCPServer tool metadata]
Client -->|MCP request + OAuth bearer when configured| Adapter
Adapter -->|request authorized session| APIs
Adapter -->|TLS handshake: session-bound certificate| Ingress
Adapter -->|HTTP request + per-request bearer when configured| Ingress
Ingress -->|verified certificate identity| Gateway
Grant --> Gateway
Session --> Gateway
Metadata --> Gateway
Gateway -->|all checks pass| Server
Gateway -->|denied or allowed decision| Audit
end
subgraph Cluster[Kubernetes operations]
Operator[Operator] -->|ServiceAccount + RBAC| KubeAPI[Kubernetes API]
KubeAPI -->|reconciles workloads and policy| Server
end
The adapter certificate proves which delegated Runtime session is calling; it does not grant tools by itself and does not contain an OAuth token. When the server enables OAuth, the client supplies a bearer on each HTTP request. Several clients can use one adapter with different tokens only when each token is valid for the same MCP resource and identifies the same human as the certificate-bound session. If a token includes a team claim, it must also match the session's team. Different Runtime agent identities need separate sessions and certificates. See Certificate identity and OAuth tokens for the request sequence.
The gateway is the tool-call enforcement point when the server uses allow-list
policy. An enabled grant and, when session.required: true, an active session
must match the caller and server. The grant must allow the tool and its
side-effect class, and effective trust must meet the tool's required level.
server init creates an allow-list policy with defaultDecision: deny, so
unmatched calls are rejected by default.
policy.mode: observe is an explicit exception: it permits calls without
enforcing those checks, while still recording decisions. A server with the
gateway disabled also has no gateway policy enforcement.
The rest of this guide breaks these checks down by resource. The detailed identity fields, decision order, and denial reasons are in Identity and authorization.
MCPServer¶
An MCPServer is a Kubernetes CRD that describes a running MCP server: what image
to run, which port it listens on, how it routes traffic, and whether the governance
gateway is enabled.
When you run mcp-runtime server deploy, the operator reconciles an MCPServer into
a Kubernetes Deployment, Service, and Ingress. If you delete one of them, the
operator recreates it.
# What the operator creates from one MCPServer
Deployment → runs your server image
Service → exposes it inside the cluster
Ingress → routes /<server-name>/mcp to the Service
The MCPServer also carries policy settings: which tools are governed, what
trust levels they require, whether allow-list checks are enabled, and whether
the gateway runs in enforcement or observe mode.
Managed agents¶
A managed agent is a platform directory record for a logical agent identity. It
is separate from the human who delegates access, the MCP client process that
sends a request, and any OAuth client_id used by that client.
Each record belongs to one team and has an immutable ID such as
agt_01arz3ndektsv4rrffq69g5fav, a changeable display name, and an active or
inactive status. The stable ID lets grants, sessions, audit events, and the
agent directory refer to the same identity even when the name or client changes.
Team ownership lets the platform check that an agent is being granted access by
and for the right team. The directory is governance metadata; the ID alone does
not authenticate a process or prove what software made a request.
Create or list records through the platform API using the CLI:
mcp-runtime agent create acme --name "Release assistant"
mcp-runtime agent list acme --status active
The create command prints the generated ID. Use that ID in MCPAccessGrant
subjects and in mcp-runtime adapter proxy --agent <agent-id>. A team owner or
platform administrator can create and manage records. Team members see active
agents only when an applicable grant or their own active session gives them
access; ask a team owner for an ID if the list is empty.
When an agent is deactivated, the platform marks the record inactive, refuses new platform-backed grants, sessions, and certificate enrollments for it, and revokes its active sessions across namespaces. The grants remain available for history and must be disabled separately if you also need to remove standing policy. Gateways apply session revocation after they load the updated policy, usually within about 10 seconds. Direct Kubernetes writes bypass the directory checks; use the platform API for managed agent access.
MCPAccessGrant¶
A grant is a policy document that says: "Agent X, acting for Team Y, is allowed to call these tools on server Z, up to this trust level, with these side effects."
Grants are scoped to a server and match a human, agent, team, or combination of those identities. With allow-list policy and the default deny decision, a caller without a matching grant cannot call tools.
MCPAccessGrant
serverRef: payments ← which server
subject:
agentID: agt_01arz3ndektsv4rrffq69g5fav ← managed agent ID
teamID: <globex-uuid> ← which team (optional)
maxTrust: low
allowedSideEffects: [read]
toolRules:
- name: list_invoices ← allowed
decision: allow
requiredTrust: low
- name: delete_invoice ← blocked
decision: deny
Grants are created with mcp-runtime access grant init and applied with
mcp-runtime access grant apply. See CLI reference: access.
MCPAgentSession¶
A session records a human, agent, and team identity for one server and a fixed period. The grant is separate standing policy; an adapter-issued session is created only when the platform finds a matching enabled grant. A session carries:
consentedTrust: the trust ceiling the user consented toexpiresAt: when the session ends (the agent must renew)revoked: set totrueto block later calls after the gateway loads the updated policy, usually within about 10 seconds
When session.required: true, the gateway checks for a matching active session
on each tool call. A missing, expired, or revoked required session denies the
call. When sessions are optional, trust falls back to the grant's maxTrust.
MCPAgentSession
serverRef: payments
subject:
agentID: agt_01arz3ndektsv4rrffq69g5fav
teamID: <globex-uuid>
consentedTrust: low ← human approved this level
expiresAt: 2030-06-02T12:00Z
revoked: false
The adapter creates or reuses a session when it starts with --server and
--agent. --auto-refresh renews the adapter certificate before it expires; it
does not refresh the OAuth token. Create sessions manually only when an
administrator needs explicit control over expiry, trust ceiling, or revocation.
Why there are two resources
A grant is standing policy, like a rule in a security handbook. A session is today's visitor badge. A call needs both when the server requires sessions. Revocation changes policy for subsequent calls after gateways load the new revision; calls already in progress are not recalled.
Grant or session: which one do I need?¶
| Scenario | Grant needed? | Session needed? |
|---|---|---|
| Agent calling tools on a server with allow-list policy | Yes | Yes when session.required: true |
| Agent calling tools on a server with optional sessions | Yes | No; trust falls back to the grant's maxTrust |
| Block an agent from a specific tool | Yes (deny rule) | — |
Limit trust to low regardless of what the agent requests |
Yes (maxTrust) |
— |
| Time-limit an agent's access | — | Yes (expiresAt) |
| Revoke an agent's later calls | — | Yes (revoked: true; allow time for policy refresh) |
| Share one server between two teams | Yes (with teamID) |
Yes (with teamID) |
Trust levels¶
Trust is a ceiling, never a grant. The gateway computes two values and compares them:
effective = min(grant.maxTrust, session.consentedTrust)
required = max(tool.requiredTrust, matchingToolRule.requiredTrust)
allowed when effective >= required
Effective trust takes the lower of what policy permits and what a human consented to, so either one can hold the line alone. Required trust takes the higher of the tool's own bar and any tighter bar in the grant's tool rule, so a grant can raise the price of a tool but never discount it.
| Level | Meaning |
|---|---|
low |
Read-only, reversible, low-risk operations |
medium |
Writes or operations with noticeable side effects |
high |
Destructive, irreversible, or high-impact operations |
Setting maxTrust: low on a grant means even if the agent claims high trust in
its session, the gateway caps it at low.
Side effects¶
Side effects classify what a tool does to data. The grant must explicitly allow the side-effect class before a call reaches the server.
| Value | When to use |
|---|---|
read |
Fetches or queries only; no state change |
write |
Creates, updates, or modifies records |
destructive |
Deletes, wipes, or makes irreversible changes |
A grant with allowedSideEffects: [read] blocks any tool whose metadata declares
sideEffect: write or sideEffect: destructive, even if that tool is in the
allow list. Trust and side effect are checked independently; both must pass.
Empty is not a wildcard
An omitted or empty allowedSideEffects authorizes nothing. A tool the
server never declared is denied too (tool_side_effect_unknown): with no
declared side effect, there is nothing for a grant to authorize.
Policy engine¶
The policy engine is the mcp-gateway decision logic plus the per-server
policy document that the operator renders for it. It is not another CRD. The
operator combines the server's policy settings and tool metadata with matching
grants and sessions, then writes the result to a policy ConfigMap beside that
server.
For each MCP tools/call, the gateway identifies the caller, finds the named
tool in the server's declared tool inventory, and evaluates the applicable
policy:
flowchart LR
Server[MCPServer policy and tool metadata] --> Render[Operator renders per-server policy]
Grant[MCPAccessGrant rules, trust, and side effects] --> Render
Session[MCPAgentSession identity and consent] --> Render
Render --> Config[Policy ConfigMap]
Call[MCP tools/call] --> Gateway[mcp-gateway]
Config --> Gateway
Gateway -->|allowed| MCP[MCP server]
Gateway -->|allowed or denied| Audit[Audit event]
In allow-list mode, the gateway checks identity, any required session, an
enabled matching grant, the tool rule, the declared side effect, and trust
before forwarding the call. The result is that server owners can change
permissions without changing server code, platform operators can keep the same
checks across servers, and each decision records a reason for later review.
server init scaffolds allow-list mode with a default deny decision. Use
policy.mode: observe to record what the policy would decide while allowing
calls during a rollout.
The engine evaluates the metadata it receives; it does not inspect a tool's implementation or infer its real-world effects. Keep the declared tool names, trust levels, and side effects aligned with the running server. Policy checks apply only when the gateway is enabled and the server is using allow-list mode; observe mode records decisions without blocking calls.
The gateway¶
The gateway, mcp-gateway, is a sidecar container in each MCP server pod (when
gateway.enabled: true on the MCPServer). Traefik routes the public path to the
pod; mcp-gateway makes the authorization decision there before the request
reaches your server.
On each tool call the gateway:
- Authenticates identity: OAuth bearer when
spec.authis set; for an adapter, resolves session identity from the verified client certificate (and binds the bearer subject to the session human when OAuth is also enabled) - Looks up the matching
MCPAccessGrantand, whensession.required: true, an activeMCPAgentSessionfor that agent and server - Checks trust level, side-effect class, and per-tool allow/deny rules
- Either forwards the call to your server or returns a denial with a reason code
- Emits an analytics event with the decision
Your server code needs no changes to support the gateway.
Two things are called \"gateway\"
mcp-gateway is the per-server enforcement sidecar inside each MCP server pod.
The platform gateway Deployment in mcp-platform is the Traefik ingress in front of the
platform APIs, ingest, and UI. It routes traffic and makes no tool-call
decisions.
Adapter¶
The adapter is a local proxy that runs on the developer's machine (or inside an agent process). It:
- Calls the platform API to create or reuse an authorized session
- Presents a certificate whose SPIFFE identity is bound to that session
- Forwards the local MCP client's OAuth bearer token when the target enables OAuth
- Refreshes the certificate automatically before it expires (
--auto-refresh)
The adapter does not make authorization decisions; the gateway does.
Your MCP client → adapter proxy (localhost:8099) → gateway → MCP server
Platform mode¶
Platform mode controls which namespace servers are published into and who can browse the catalog without logging in.
| Mode | Who sees servers | Catalog namespace |
|---|---|---|
org (default) |
Signed-in users browse the org catalog and their authorized teams | mcp-servers-org |
public |
Anyone browses the public catalog; signed-in users also browse org and their authorized teams | mcp-servers-public and mcp-servers-org |
There are two platform modes and three publish scopes. tenant is a team
publish scope, not a platform mode. Org mode accepts tenant and org;
public mode accepts tenant, org, and public. Organization and team
namespaces remain unavailable to anonymous catalog readers in public mode.
Set with --platform-mode on setup or MCP_SETUP_PLATFORM_MODE in your env file.
Scopes¶
When publishing a server image (server push) or deploying a server
(server deploy), --scope controls which catalog namespace the server lands in:
| Scope | Namespace | Who can use it |
|---|---|---|
tenant |
mcp-team-<slug> |
Members of that team |
org |
mcp-servers-org |
All signed-in users in the org |
public |
mcp-servers-public |
Anyone |
These scopes control catalog visibility. Calling a tool still follows the server's authentication and gateway policy; public catalog visibility does not disable tool authentication. Public scope supports live previews and MCP servers a company wants to list for public use on this platform.
What's in a .mcp/servers.yaml¶
The .mcp/servers.yaml file is the metadata file that server init creates.
It is the source of truth for your server's tool policy. The gateway enforces
what is declared here, and calls to unlisted tools are denied.
servers:
- name: payments
image: registry.example.com/acme/payments
imageTag: v1
scope: tenant
tools:
- name: list_invoices # must match the real tool name in your server
requiredTrust: low
sideEffect: read
- name: create_invoice
requiredTrust: medium
sideEffect: write
policy:
mode: allow-list
defaultDecision: deny # deny everything not in the list
session:
required: true
gateway:
enabled: true
Use server init --from-server http://localhost:8088 to generate this file
automatically from a running server's tools/list response rather than writing
it by hand. Then run server validate before deploying to catch mismatches.
policy.mode: observe is a migration tool, not a setting to leave on
Observe mode allows every tool call before identity, session, grant,
side-effect, and trust checks run. Traffic is still proxied and audited, so use
it to see what enforcement would deny on a new server, fix the tool
inventory, then switch back to allow-list.
Next: Identity and Authorization explains how grants, sessions, certificates, and OAuth combine in an access decision. For a hands-on workflow, follow Server and Client Guides.