Agent HTTP Adapter¶
Use mcp-runtime adapter proxy to connect Claude Desktop, Cursor, or another
MCP client to a server on your platform. It runs beside the client: the client
connects to a local URL, and the adapter forwards requests to the platform over
HTTPS.
The adapter gets a certificate for the agent's session and keeps it refreshed. On an installation configured to verify these certificates, the gateway uses it to identify the human, agent, team, and session making a tool call. If the server also requires OAuth, the client must send its bearer token; the adapter forwards it on each request. The token's user must match the session's user, and any team claim must match the session. The gateway does not trust identity headers supplied by the client.
Use an active managed agent from the team's agent directory. List agents with
mcp-runtime agent list <team-slug> --status active; a team owner or platform
admin can create one with mcp-runtime agent create <team-slug> --name <name>.
Members see only agents covered by an applicable grant or their own active
session, so ask a team owner for an ID if the list is empty. Use the immutable
agt_... ID returned by the directory in the grant and adapter commands below.
A display name such as Cursor is not an agent ID.
Inspect authorization in the dashboard¶
Open Agents, select an agent, and inspect its visible session history. Each session shows the authorizing human and the exact namespace/name of its recorded grant. Follow either the session or grant link to the shared access detail view. A missing link is labelled unknown; the UI does not guess a grant from overlapping rules. Records outside your permitted scope remain unavailable.
The lifecycle summary counts visible active, expired and revoked sessions. Before deactivation, the confirmation lists visible sessions that will lose access. Afterward, it re-reads agent and session state, shows recorded revocation causes, and keeps partial failures visible. Counts cover your view; deactivation also revokes sessions outside it. Reactivation preserves the ID and history and does not restore revoked sessions.
Administrators can open Administration → Usage analytics → Gateway audit and load the latest 100 events. Matched grant/session links include their recorded namespaces. The shared detail view queries the most recent 1,000 matching events from the last seven days and shows loaded allow/deny/would-deny counts. This is a bounded view of delivered events, not a complete usage total. Gateway events remain restricted to administrators; an unavailable analytics service is shown as an error rather than an empty history.
Required grant¶
Create an enabled MCPAccessGrant before starting the adapter. The grant must
match the target server and agent. The platform refuses session and certificate
issuance when no grant matches.
apiVersion: mcpruntime.org/v1alpha1
kind: MCPAccessGrant
metadata:
name: triage-grant
namespace: mcp-team-acme
spec:
serverRef:
name: workspace-assistant
subject:
agentID: agt_01arz3ndektsv4rrffq69g5fav # replace with your active agent ID
maxTrust: high
allowedSideEffects: [read]
policyVersion: v1
toolRules:
- name: add
decision: allow
In-memory enrollment¶
Log in, then start the proxy with the server and agent identifiers:
mcp-runtime auth login --api-url https://platform.example.com
mcp-runtime adapter proxy \
--runtime-url https://mcp.example.com/workspace-assistant/mcp \
--server workspace-assistant \
--namespace mcp-team-acme \
--agent agt_01arz3ndektsv4rrffq69g5fav \
--auto-refresh
For an OAuth-enabled target, the local MCP client normally completes OAuth and
sends Authorization to the adapter. The proxy preserves it for each request.
For a client that cannot attach the header, set --auth-header "Bearer
<access-token>"; this static value is used for every request. Omit it when the
target has no OAuth configuration or when clients need to send different
tokens.
The adapter:
- Requests an
MCPAgentSessionthat is authorized by the matching grant. - Generates the private key and CSR locally.
- Sends the CSR to the platform certificate endpoint.
- Receives the signed leaf certificate and CA bundle.
- Presents the certificate during the HTTPS handshake and forwards each request's OAuth bearer when the target requires one.
- Renews the certificate before it expires when
--auto-refreshis enabled.
The private key never leaves the adapter process.
Certificate identity and OAuth tokens¶
The adapter certificate identifies one MCPAgentSession; it does not identify
an individual MCP protocol session or contain an OAuth token. The certificate
is presented during the HTTPS handshake. The local MCP client sends its OAuth
bearer on each HTTP request, and the proxy forwards that request's
Authorization header over the authenticated connection. The gateway checks
the certificate identity and, when OAuth is enabled, requires the token subject
to match the session's human and any team claim to match the session's team.
sequenceDiagram
participant C1 as Claude / MCP client A
participant C2 as Cursor / MCP client B
participant A as One adapter proxy
participant P as Platform API
participant T as Traefik
participant G as MCP gateway
participant S as MCP server
A->>P: Authenticate and issue or reuse authorized session
P-->>A: Session identity and expiry
A->>A: Generate private key and CSR
A->>P: Enroll certificate for the session
P-->>A: Signed certificate and CA bundle
A->>T: Establish HTTPS and present certificate in TLS handshake
Note over A,T: The certificate represents one MCPAgentSession
C1->>A: MCP request + bearer token A
A->>T: Forward request + token A on authenticated connection
T->>G: Request + verified certificate identity + token A
G->>G: Resolve session and validate token and subject
G->>S: Authorized request + token A
S-->>G: MCP response
G-->>T: MCP response
T-->>A: MCP response
A-->>C1: MCP response
C2->>A: MCP request + bearer token B
A->>T: Forward request + token B on authenticated connection
T->>G: Request + same certificate identity + token B
G->>G: Resolve same session and validate token and subject
G->>S: Authorized request + token B
S-->>G: MCP response
G-->>T: MCP response
T-->>A: MCP response
A-->>C2: MCP response
This works when both OAuth tokens are valid for the target MCP resource and identify the same human as the certificate-bound session. A token for another human is rejected. Both clients' calls are attributed to the same Runtime agent and session. If clients need distinct Runtime agent identities or session-level audit attribution, run a separate adapter proxy with its own certificate for each identity.
The default listener is 127.0.0.1:8099 and does not authenticate local
clients. Any process that can connect to it can make calls using that adapter
session. Keep it on loopback and share it only among clients intended to act as
the same Runtime agent and human.
Do not set --auth-header when clients need different OAuth tokens. It is a
static override applied to every outbound request, so it replaces each
client's per-request bearer. Let each client send its own Authorization
header instead. --auto-refresh refreshes the adapter certificate; each MCP
client remains responsible for obtaining and refreshing its OAuth token.
Save a certificate¶
Use adapter enroll when another process manages the proxy lifecycle:
mcp-runtime adapter enroll \
--server workspace-assistant \
--namespace mcp-team-acme \
--agent agt_01arz3ndektsv4rrffq69g5fav
The command saves credentials below
$MCP_RUNTIME_CONFIG_DIR/certs/<scope>; the default root is
~/.mcpruntime/certs. The scope is deterministic for the platform, namespace,
server, agent, and SPIFFE identity. The command prints the exact directory.
client.keyis the locally generated private key, mode0600.client.crtis the session-bound leaf certificate, mode0600.ca.crtis the CA bundle used to verify the runtime TLS certificate.
Start the proxy with the saved files:
mcp-runtime adapter proxy \
--runtime-url https://mcp.example.com/workspace-assistant/mcp \
--tls-client-cert ~/.mcpruntime/certs/<scope>/client.crt \
--tls-client-key ~/.mcpruntime/certs/<scope>/client.key \
--tls-ca-bundle ~/.mcpruntime/certs/<scope>/ca.crt
For an OAuth-enabled target, the local MCP request must still carry
Authorization, or the proxy must be started with --auth-header. The
certificate files identify the enrolled Runtime session; the OAuth bearer is
still a separate per-request credential.
CA bundle and CSR flow¶
The adapter creates a private key and a PKCS#10 CSR containing the expected
session SPIFFE URI. The platform validates the CSR against the issued
MCPAgentSession, signs it with the configured workload issuer, and returns:
- the signed client certificate;
- the CA certificate chain required to verify platform TLS certificates;
- the SPIFFE ID and expiry time.
The CA bundle does not receive or sign the CSR itself. The platform certificate endpoint submits the validated request to the configured issuer and returns the issuer's chain as the bundle.
macOS background adapter and companion¶
The macOS CLI can run isolated adapter profiles in a per-user background service. Each profile is explicitly authorized for one platform, team, human, agent, server and session; local MCP clients receive a separate owner-only credential. Session expiry still requires interactive authorization. The native companion is a normal Dock app with one status/control window. It uses the bundled CLI's protected management API, never reads credential storage, and leaves the daemon running when closed or quit. It reports local readiness separately from measured upstream authorization, profile identity, certificate expiry and redacted errors. Reconnect renews only the existing session; a new consent lifetime still requires interactive CLI authorization.
mcp-runtime adapter profile add work \
--runtime-url https://mcp.example.com/workspace-assistant/mcp \
--namespace mcp-team-acme \
--server workspace-assistant \
--agent agt_01arz3ndektsv4rrffq69g5fav
mcp-runtime adapter service install
mcp-runtime adapter profile client-config work --output ~/mcp-work.json
mcp-runtime adapter service status
profile add uses the selected interactive platform login to authorize the
session. client-config refuses to overwrite an existing file and writes the
local credential with mode 0600; protect that file as a credential. The
daemon binds only to IPv4 loopback, rejects browser-origin requests, and
requires the profile's local token. service logs and service status report
fixed redacted events and measured state, not certificates, private keys,
tokens or MCP payloads. service uninstall preserves profiles unless
--purge is supplied. This daemon slice is for macOS and is not a substitute
for the existing foreground adapter proxy workflow on other platforms.
The companion targets macOS 13 or later on Apple Silicon and Intel. Its
authoritative target and Swift 5 language mode are in desktop/macos/build.sh;
use Xcode 14 or later from Apple's Xcode distribution
and select its command-line tools (xcode-select --install for the standalone
tools). These requirements were reviewed on 2026-10-17; this change does not
upgrade a developer's installed toolchain. Build each
architecture on a Mac with those tools and the Go version in
go.mod; these commands compile/package without opening the app or starting
the daemon:
bash desktop/macos/build.sh arm64 dist
bash desktop/macos/build.sh amd64 dist
PR build artifacts are explicitly unsigned previews. They are not the
signed/notarized distribution. For distribution, configure a Developer ID
Application identity and a notarytool profile in the build user's Keychain,
then set MCP_DESKTOP_SIGNING_IDENTITY and MCP_DESKTOP_NOTARY_PROFILE to those
names and add --sign to each build command. Signing runs inside-out with the
hardened runtime, submits to Apple, staples the accepted ticket and verifies
Gatekeeper before producing *-notarized.zip. See Apple's
notarization workflow
and Developer ID guidance.
Install the app in Applications and use Install and enable login startup after configuring profiles. To update, replace the app and reinstall the service from it; the CLI copies a stable managed binary and preserves profiles. The app and daemon require management protocol version 1. To remove startup and stop the daemon, choose Uninstall service; deleting the app alone does not uninstall the daemon. Remove stored profiles only through the explicit CLI purge option. Signing/notarization and real macOS sleep/wake, install/update/ uninstall and two-profile desktop acceptance still need release evidence; Linux/headless compilation checks cannot establish those results.
Optional header mode¶
Use header mode when the MCP server authenticates the caller with its own credential headers and a Runtime certificate is not required. The adapter is optional: a direct client can send those headers itself. Header mode does not enroll a certificate, create a platform session, or invent a Runtime identity.
mcp-runtime adapter proxy \
--auth-mode header \
--runtime-url https://mcp.example.com/pilot/mcp \
--credential-header-env X-Example-Credential=EXAMPLE_TOKEN \
--credential-header-env Authorization=EXAMPLE_AUTHORIZATION
The same settings can live in a YAML file passed with --config. The file
stores source references, never secret values. Environment sources are read
from this process and change only when the adapter restarts. File sources are
reread on each request, so a mounted secret can rotate without a restart.
Relative file paths resolve from the config file's directory.
authMode: header
runtimeURL: https://mcp.example.com/pilot/mcp
credentialHeaders:
X-Example-Credential:
env: EXAMPLE_TOKEN
Private-Token:
file: ./private-token
Every configured header is injected unchanged. There is no built-in list of
header names or credential schemes. The value is pinned to that HTTPS URL.
The adapter does not follow a redirect to another target. A client-supplied
value that differs from the configured source is rejected. --auth-header
cannot also supply Authorization. Verified HTTPS is required for credential
injection, including when certificate mode injects a credential. Header mode
does not accept a client certificate or --tls-insecure-skip-verify.
Configuration¶
| Environment variable | Purpose |
|---|---|
MCP_RUNTIME_AUTH_MODE |
certificate (default) or header. Header mode skips certificate enrollment. |
MCP_RUNTIME_URL |
Absolute HTTPS Streamable HTTP MCP route. |
MCP_RUNTIME_ADAPTER_SERVER / MCP_RUNTIME_ADAPTER_AGENT |
Server and agent for in-memory certificate enrollment. |
MCP_RUNTIME_ADAPTER_NAMESPACE |
Target namespace. |
MCP_RUNTIME_ADAPTER_AUTO_REFRESH |
Renew an in-memory certificate before expiry. |
MCP_PLATFORM_API_URL |
Platform API base URL. |
MCP_TRUST_DOMAIN |
Optional SPIFFE trust domain check. |
MCP_RUNTIME_TLS_CLIENT_CERT / _KEY |
Externally managed PEM client certificate and key. |
MCP_RUNTIME_TLS_CA_BUNDLE |
PEM CA bundle used to verify the runtime. |
MCP_RUNTIME_AUTH_HEADER |
Static OAuth Authorization override when the local MCP client does not send one; it does not set adapter identity and is used for every request. |
MCP_RUNTIME_HOST_HEADER |
Override the HTTP Host header for ingress routing. |
MCP_RUNTIME_LISTEN_ADDR |
Local proxy listener; defaults to 127.0.0.1:8099. |
MCP_RUNTIME_REQUEST_TIMEOUT |
Timeout for adapter to runtime requests. |
MCP_RUNTIME_MAX_INBOUND_BYTES |
JSON-RPC request body limit; defaults to 16 MiB. |
MCP_RUNTIME_LOG_LEVEL |
info logs runtime denials to stderr. |
Non-HTTPS runtime URLs, missing certificates, invalid key pairs, and certificate enrollment failures stop the adapter before it begins listening. When the target enables OAuth, the gateway also rejects requests that lack a bearer token or whose OAuth subject does not match the certificate's enrolled session. When OAuth is omitted, the verified certificate alone authenticates the adapter.
Enterprise mTLS and SPIFFE¶
To authenticate adapters with session-bound client certificates, install
cert-manager and an internal ClusterIssuer backed by your company CA, Vault,
ADCS, or another workload PKI. Do not use Let's Encrypt for client certificates.
Production requires a Ready issuer with an independent workload signing root;
setup rejects the shared bundled registry CA and aliased/copied signing keys.
The PKI owner manages encrypted off-host recovery, overlapping trust and leaf
renewal: see CA lifecycle.
Local setup --test-mode installs cert-manager and provisions the bundled
mcp-runtime-ca ClusterIssuer automatically so this flow can be validated on
Kind without public DNS or a production CA.
mcp-runtime setup \
--with-tls \
--tls-cluster-issuer letsencrypt-prod \
--mtls-cluster-issuer company-workload-ca
Adapter certificate authentication on gateway server routes is opt-in: set
MCP_ADAPTER_CERTIFICATES=true for setup (it passes it to the operator) in
addition to naming a workload issuer with --mtls-cluster-issuer. Enabling it
moves every gateway-enabled server that uses the Traefik ingress class from a
plain Ingress to a Traefik IngressRoute, and puts the gateway behind an mTLS hop
that only Traefik can reach; servers are then no longer reachable directly on
their Service. It requires --with-tls because Traefik terminates client TLS;
the IngressRoute uses the operator's configured ingress entrypoints (websecure
when none are set). --tls-cluster-issuer controls public ingress and registry
certificates and is separate from the workload issuer. Set MCP_TRUST_DOMAIN to
the platform's SPIFFE trust domain. Production must configure both
MCP_TRUST_DOMAIN and MCP_SETUP_MTLS_CLUSTER_ISSUER; test mode defaults the
issuer to mcp-runtime-ca.
Enrollment checks this deployed operator choice before creating a session. The
operator and runtime API must use the same workload issuer and trust domain,
and the selected IngressRoute must request and verify client certificates using
the configured workload CA bundle. Preflight reads deployment/ConfigMap, issuer,
route and TLSOption metadata; it never reads certificate private keys. Secret-backed
operator configuration is reported as unavailable. Normal mcp-runtime update
installs these read-only permissions and preserves the existing on/off choice.
If certificate issuance later fails, the CLI conditionally deletes only its new
pending enrollment, with a bounded cleanup attempt even after cancellation.
Completion and cleanup check current session state under the same store lock as
revocation, so cleanup cannot remove a completed session or reactivate a revoke.
Approval gate. The runtime API creates the session certificate as a
cert-manager CertificateRequest against the workload issuer, and cert-manager
auto-approves requests to built-in issuers by default. Any other principal able
to create a CertificateRequest for that issuer could therefore obtain a
certificate with a forged SPIFFE URI outside the runtime API's session checks.
Outside --test-mode, setup refuses MCP_ADAPTER_CERTIFICATES=true unless
MCP_WORKLOAD_ISSUER_APPROVAL_ACK=true asserts that an effective approver gates
the issuer (Staging E2E sets this for its disposable VM). Installing the
approver-policy CRD alone does not establish a policy or disable cert-manager's
default auto-approver; either condition can leave forged requests approvable.
Before acknowledging the gate, verify that the policy allows only the runtime
API service account, digital signature +
client auth usages, and the spiffe://<trust-domain>/ns/<ns>/session/<name>
URI shape, and the default approver should be disabled for this issuer only after
that policy is tested (keep public and internal TLS issuance working, and roll
back by re-enabling the default approver). The runtime API also rejects any
issued certificate whose URI, key, usages, or lifetime differ from the submitted
CSR, and its ClusterRole only grants create and get on CertificateRequests.
Approval policies for production. config/cert-manager/approval-policies.yaml
holds the hosted policy set. Turning off cert-manager's default approver is
cluster-wide, so every request the platform makes needs a policy:
| Policy | Requester | Issuer | Allows |
|---|---|---|---|
mcp-session-certificates |
mcp-platform/mcp-runtime-api |
mcp-runtime-ca |
one spiffe://<trust-domain>/ns/*/session/* URI, usages digital signature + client auth, no DNS names, not a CA |
mcp-workload-tls |
cert-manager/cert-manager |
mcp-runtime-ca |
gateway/registry server certificates and the Traefik proxy URI only; never a session URI |
mcp-public-acme |
cert-manager/cert-manager |
letsencrypt-prod |
mcpruntime.org and *.mcpruntime.org server certificates |
Adjust the trust domain and the Traefik identity in the file to match
MCP_TRUST_DOMAIN and MCP_INGRESS_CONTROLLER_*, and the public domain to your
own. A request that no policy applies to is never approved and never issued; it
stays pending.
Rehearse first on a throwaway Kind cluster (it creates and removes its own cluster and kubeconfig, and asserts approval, denial and renewal):
hack/qa/approval-policy-rehearsal.sh
The rehearsal pins cert-manager v1.21.2, approver-policy v0.28.0 and a
digest-pinned Kubernetes 1.36.4 Kind node (reviewed 2026-10-17). It refuses an
existing cluster name and keeps Helm state inside its temporary directory.
The node pin comes from Kind v0.33.0;
cert-manager's support matrix covers
Kubernetes 1.33–1.36 for the 1.21 series. The Workload Issuer Approval PR workflow
runs this headless admission matrix on its own GitHub runner.
These are admission tests using direct CertificateRequests, including hidden
otherName/directoryName SANs; they do not replace the supported CLI adapter
enrollment journey. The runtime API and adapter also inspect the complete SAN
extension, because Go's parsed URI/DNS fields omit those additional name types.
Approver-policy versions before v0.27.0 lack fixes for raw SAN and subject
validation bypasses; use the reviewed pin rather than the former v0.17.0 example.
See the upstream security fixes
and v0.28.0 maintenance release.
Then, in this order, with the production kubeconfig passed explicitly:
- On cert-manager v1.21.2, install the reviewed approver:
helm upgrade --install approver-policy oci://quay.io/jetstack/charts/cert-manager-approver-policy --version v0.28.0 -n cert-manager --wait. Confirm its Deployment is ready. It changes no approval decisions while the default approver is still enabled. kubectl apply -f config/cert-manager/approval-policies.yamland confirm all three policies reportReady=True.- Add
--controllers=*,-certificaterequests-approverto thecert-managerDeployment arguments. Keep a copy of the Deployment YAML first. - Verify a gateway certificate and a session certificate still issue, and that
no legitimate
CertificateRequestis left pending. Negative requests must remain denied or unapproved with no issued certificate. - Only then set
MCP_WORKLOAD_ISSUER_APPROVAL_ACK=truefor setup and enableMCP_ADAPTER_CERTIFICATES=trueon the operator.
To roll back, remove that argument (or reapply the saved Deployment); the default approver resumes immediately. Install approver-policy and its policies before disabling the default approver, never after.
OAuth is independent. Omit spec.auth for a cert-only governed route; add
spec.auth only when direct clients (or adapters calling an OAuth-enabled
target) need a bearer. Do not apply empty auth: {} unless you intend to turn
OAuth on via the derived issuer.
# Cert-only (adapters present the session certificate; no bearer required)
spec:
ingressHost: mcp.mcpruntime.org
publicPathPrefix: workspace-assistant
ingressClass: traefik
gateway:
enabled: true
# omit auth
# Optional OAuth on the same certificate-capable route
spec:
ingressHost: mcp.mcpruntime.org
publicPathPrefix: workspace-assistant
ingressClass: traefik
gateway:
enabled: true
auth:
mode: oauth
issuerURL: https://auth.mcpruntime.org
audience: https://mcp.mcpruntime.org/workspace-assistant/mcp
How termination works. Traefik verifies a presented adapter client
certificate against the platform workload CA, asserts the verified SPIFFE
identity to the gateway, and re-encrypts over a second mTLS hop. Client-supplied
X-MCP-* identity headers are not trusted. Ordinary OAuth clients without a
client certificate continue with Bearer only on OAuth-enabled servers. The
operator generates the Traefik TLSOption (VerifyClientCertIfGiven), the
spiffe-identity middleware, a ServersTransport (re-encrypted hop with a
pinned ingress certificate), and a path-based IngressRoute. A
NetworkPolicy restricts the gateway port to the ingress so the SPIFFE
assertion cannot be forged by another pod, and the gateway requires a
verified mTLS hop before trusting that assertion.
The caller-facing server certificate for the route is published as Traefik's
default certificate via a single TLSStore named default, not a
per-IngressRoute secretName (Traefik resolves secretName only in the
IngressRoute's own tenant namespace, where the shared platform host certificate
does not exist). Configure the operator with MCP_DEFAULT_INGRESS_TLS_SECRET
(the host certificate Secret) and MCP_DEFAULT_INGRESS_TLS_SECRET_NAMESPACE (a
Traefik-watched namespace holding that Secret); the operator then reconciles the
one default TLSStore there. When unset, Traefik falls back to its built-in
default certificate.
Kind contributor cluster. Adapter-certificate IngressRoutes are websecure-only. Port-forward both Traefik ports and probe HTTPS with an insecure TLS skip for the local default cert:
kubectl port-forward -n traefik svc/traefik 18080:8000 18443:8443
# Platform / plain Ingress samples: http://127.0.0.1:18080/...
# Adapter-certificate MCP routes: https://127.0.0.1:18443/<publicPathPrefix>/mcp
Enroll an external adapter after signing in to the platform:
mcp-runtime adapter enroll \
--platform-url https://platform.mcpruntime.org \
--server workspace-assistant \
--namespace mcp-team-acme \
--agent agt_01arz3ndektsv4rrffq69g5fav \
--trust-domain mcpruntime.org
The command generates client.key locally and submits only a CSR. The platform
checks that the SPIFFE URI identifies a session owned by the signed-in
principal, then returns short-lived client.crt and ca.crt under
MCP_RUNTIME_CONFIG_DIR/certs (normally ~/.mcpruntime/certs).
--platform-url takes scheme and host with no /api path, and defaults to the
URL saved by auth login or $MCP_PLATFORM_API_URL. Because enrollment is
session-bound, the grant prerequisite above applies here too.
mcp-runtime adapter proxy \
--runtime-url https://mcp.mcpruntime.org/workspace-assistant/mcp \
--tls-client-cert ~/.mcpruntime/certs/<scope>/client.crt \
--tls-client-key ~/.mcpruntime/certs/<scope>/client.key \
--tls-ca-bundle ~/.mcpruntime/certs/<scope>/ca.crt
One-command mode¶
Pass --server and --agent to adapter proxy so it enrolls a session-bound
certificate in memory at startup (nothing is written to disk) and feeds it
straight to the runtime transport:
mcp-runtime adapter proxy \
--runtime-url https://mcp.mcpruntime.org/workspace-assistant/mcp \
--platform-url https://platform.mcpruntime.org \
--server workspace-assistant \
--namespace mcp-team-acme \
--agent agt_01arz3ndektsv4rrffq69g5fav \
--trust-domain mcpruntime.org \
--auto-refresh
In-memory enrollment requires an https --runtime-url and the same
--server/--agent inputs as enroll (the certificate's SPIFFE URI encodes
the issued session). With --auto-refresh, the adapter enrolls a replacement
certificate before the current certificate expires and drains idle
connections so subsequent requests renegotiate with it. Long-running adapters
keep working without restarts. To reuse enroll output instead of in-memory
enrollment, pass the --tls-client-cert/-key/-ca-bundle files.
Adapters authenticate with the session-bound certificate; grant and session
policy authorize that identity. On OAuth-enabled targets they also forward the
bearer and the gateway binds the certificate session human to the OAuth
subject. Existing MCPServer resources using the removed auth.mode: mtls must
omit spec.auth for cert-only routes or set auth.mode: oauth with
issuerURL and audience when OAuth is required. Set platform-wide
MCP_TRUST_DOMAIN and MCP_MTLS_CLUSTER_ISSUER to enable adapter enrollment;
test-mode defaults the issuer to mcp-runtime-ca.
The gateway derives adapter governance identity from the verified SPIFFE URI and the operator-rendered session binding.
Next steps¶
Verify an allowed and a denied tool call, then inspect the gateway decisions in Services and Observability. For identity or policy failures, use Troubleshooting and Identity and Authorization.
For a server requiring OAuth, follow MCP OAuth for token and resource configuration. Return to Server and Client Guides for the complete publishing and access flow.
Server authentication badges¶
The catalog shows OAuth when the server reports OAuth support, and Header when it uses caller-supplied credential headers. Servers without reported authentication support have no authentication badge. OAuth support does not itself mean every connection requires an OAuth token; use the server's connection instructions and adapter requirements.