diff --git a/README.md b/README.md
index b938d72e..ed602d86 100644
--- a/README.md
+++ b/README.md
@@ -2,7 +2,7 @@
-# cMCP
+# cMCP: Confidential MCP Runtime
### Enforce MCP tool policy where it cannot be tampered with
@@ -26,6 +26,8 @@
> **Developer Preview** - launching at Confidential Computing Summit, June 23 2026. May have breaking changes before v1.0.
+Your agent calls Snowflake, Salesforce, a dozen APIs. What stops it from leaking a customer's data on one of those calls? If a regulator asks, could you prove it didn't?
+
---
## The problem
@@ -40,6 +42,10 @@ None of that proves the policy engine itself was not compromised. Software-only
The control plane that governs tool calls must run where it cannot be reached by the process it governs.
+Hardware-attested policy enforcement for MCP tool calls. Every tool call is intercepted, evaluated against a Cedar policy bundle, and enforced by a policy engine running inside a Trusted Execution Environment (TEE). The policy bundle hash is measured into the hardware attestation report before any code runs.
+
+Unlike tunnel-based connectivity solutions, the cMCP Runtime processes tool-call payloads inside the TEE. The connectivity provider sees ciphertext, not plaintext. The only thing that leaves the enclave is the signed TRACE claim.
+
---
## Quick Start
@@ -84,7 +90,7 @@ See [docs/quickstart.md](docs/quickstart.md) for the full walkthrough: Cedar pol
4. At the end of the session the gateway produces a TRACE Claim: a signed, hardware-attested artifact that records which tools ran, which policy decided each call, and the full audit chain. A verifier checks this without trusting the operator.
```
-Agent -> cMCP Gateway -> Cedar Policy Engine (TEE) -> Tool
+Agent -> cMCP Runtime -> Cedar Policy Engine (TEE) -> Tool
|
GatewayClaim (TRACE Profile)
+-- trace.eat_profile
@@ -105,7 +111,7 @@ Agent -> cMCP Gateway -> Cedar Policy Engine (TEE) -> Tool
| `sev-snp` | AMD SEV-SNP (Azure DCasv5, AWS C6a Nitro) | High | AMD KDS |
| `tdx` | Intel TDX (Azure DCedsv5, GCP C3) | High | Intel PCS |
| `gpu-cc` _(v0.2)_ | NVIDIA H100/H200/Blackwell (CC mode) | High | NVIDIA Remote Attestation Service (NRAS) |
-| `opaque` _(explicit opt-in)_ | Opaque Managed Runtime | High | Set `OPAQUE_ATTESTATION_URL`; not in auto-detect chain |
+| `opaque` _(explicit opt-in)_ | OPAQUE Confidential Runtime | High | Set `OPAQUE_ATTESTATION_URL`; not in auto-detect chain (stub: detect() returns False, not yet implemented) |
Provider auto-detects: `SEV-SNP -> TDX -> TPM -> software`. `opaque` is explicit opt-in via `OPAQUE_ATTESTATION_URL` and is never selected automatically.
diff --git a/docs/README.md b/docs/README.md
index c5af3a15..689f0926 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -1,8 +1,8 @@
-# cMCP Spec
+# cMCP Spec
-cMCP Gateway is a hardware-attested MCP (Model Context Protocol) gateway. Every MCP tool call an agent makes passes through a TEE-isolated gateway that evaluates it against a Cedar policy bundle and produces a TRACE Claim: a signed, hardware-attested proof artifact a verifier can check without trusting the operator.
+cMCP Runtime is a hardware-attested MCP (Model Context Protocol) runtime. Every MCP tool call an agent makes passes through a TEE-isolated gateway that evaluates it against a Cedar policy bundle and produces a TRACE Claim: a signed, hardware-attested proof artifact a verifier can check without trusting the operator.
-Phase 1 attests the agent-to-tool boundary on the consumer side (the gateway). Phase 2 attests it on the provider side (the server). Together they close the proof gap that software-only gateways leave open: "prove that the policy you describe in documents is the policy that actually ran on your traffic."
+Phase 1 attests the agent-to-tool boundary on the consumer side (the runtime). Phase 2 attests it on the provider side (the server). Together they close the proof gap that software-only runtimes leave open: "prove that the policy you describe in documents is the policy that actually ran on your traffic."
This repository contains the product specification. Implementation lives in a separate repo.
@@ -13,11 +13,11 @@ This repository contains the product specification. Implementation lives in a se
**Understanding the problem space:**
Read SPEC.md. It defines the four problems (P1 data leakage, P2 unsanctioned tools, P3 provable governance, P4 supply chain), the 13 threat shapes, and the coverage matrix showing what Phase 1 closes vs. what Phase 2 closes.
-**Implementing the gateway (Phase 1):**
+**Implementing the runtime (Phase 1):**
Read in this order:
1. SPEC.md — problem context and scope
2. docs/spec/component-model.md — what you are building and where trust boundaries are
-3. docs/spec/transport.md — how the gateway intercepts MCP traffic
+3. docs/spec/transport.md — how the runtime intercepts MCP traffic
4. docs/spec/attestation.md — how TEE attestation works and how to produce TRACE Claims
5. docs/spec/cedar-policy.md — the policy engine, bundle format, and enforcement modes
6. docs/spec/failure-modes.md — what happens when things go wrong
@@ -38,11 +38,11 @@ Issues in this repo track spec decisions, not implementation bugs. Each issue co
| docs/spec/attestation.md | TEE provider detection, audit chain, key management, catalog pinning | 1 | Draft v0.1 | #5, #6, #23, #33, #38 |
| docs/spec/cedar-policy.md | Policy bundle format, Cedar examples, enforcement modes, provenance | 1 | Draft v0.1 | #4, #7, #26, #39, #41 |
| docs/spec/tool-identity.md | Server identity binding, catalog schema, collision detection | 1 | Draft v0.1 | #40 |
-| docs/spec/failure-modes.md | Gateway failure scenarios, decision table, log formats | 1 | Draft v0.1 | #22 |
+| docs/spec/failure-modes.md | Runtime failure scenarios, decision table, log formats | 1 | Draft v0.1 | #22 |
| docs/spec/call-graph.md | Tag-propagation model, observability limits, cross-boundary policy | 1 | Draft v0.1 | #35 |
| docs/spec/session-policy.md | Session sensitivity state machine, egress policy, session reset | 1 | Draft v0.1 | #36 |
| docs/spec/response-inspection.md | 4-stage response inspection pipeline, injection patterns | 1 | Draft v0.1 | #37 |
-| docs/spec/error-codes.md | Central error code registry for all gateway and verification errors | 1+2 | Draft v0.1 | — |
+| docs/spec/error-codes.md | Central error code registry for all runtime and verification errors | 1+2 | Draft v0.1 | — |
| docs/spec/threat-model.md | Assets, adversaries, STRIDE analysis per component | 1 | Draft v0.1 | #18, #24 |
| docs/spec/verification-library.md | cmcp-verify Python library interface and per-provider verification steps | 1 | Draft v0.1 | #25 |
| docs/spec/mcp-spec-strategy.md | MCP spec monitoring and attestation extension contribution window | 1+2 | Draft v0.1 | #30 |
@@ -105,14 +105,14 @@ A conforming implementation passes all MUST-level tests. SHOULD-level tests indi
| Term | Definition |
|------|-----------|
-| TRACE Claim | The signed, hardware-attested proof artifact produced by the gateway per session |
+| TRACE Claim | The signed, hardware-attested proof artifact produced by the runtime per session |
| TEE | Trusted Execution Environment (TPM, SEV-SNP, TDX, or Opaque Managed) |
| SPIFFE SVID | Short-lived cryptographic identity issued by SPIRE after TEE attestation succeeds |
| Cedar | The policy language used for tool call authorization |
-| Audit chain | The append-only hash-chained log of all gateway decisions, signed with a TEE-sealed key |
+| Audit chain | The append-only hash-chained log of all runtime decisions, signed with a TEE-sealed key |
| Session sensitivity | The maximum sensitivity level seen in any tool response within the current session |
-| Tag-propagation | The gateway's mechanism for tracking sensitivity across calls based on observable events |
-| Catalog entry | The gateway's approved record for one tool: name, server identity, approved definition |
+| Tag-propagation | The runtime's mechanism for tracking sensitivity across calls based on observable events |
+| Catalog entry | The runtime's approved record for one tool: name, server identity, approved definition |
| Attestation report | The hardware-produced evidence that a specific binary ran in a specific TEE at a specific time |
| policy_bundle_hash | SHA-256 of the canonical Cedar policy bundle, measured into the TEE at startup |
| tool_catalog_hash | SHA-256 of the canonical tool catalog, measured into the TEE at startup |
diff --git a/docs/SPEC.md b/docs/SPEC.md
index 52777764..3d777b24 100644
--- a/docs/SPEC.md
+++ b/docs/SPEC.md
@@ -1,4 +1,4 @@
-# cMCP Gateway - Product Specification
+# cMCP Runtime - Product Specification
Status: Draft | Target: CC Summit June 23, 2026
Primary opportunity: Enterprises cannot prove to regulators, auditors, or customers how their data was handled during AI processing.
@@ -79,9 +79,9 @@ The gateway and the server are now primary control surfaces -- the only enforcem
---
-## 3. Solution: cMCP Gateway
+## 3. Solution: cMCP Runtime
-The cMCP Gateway intercepts every MCP tool call, evaluates it against a Cedar policy bundle, and enforces the result from inside a TEE. The policy bundle hash is measured into the hardware attestation report before any code runs. The audit chain is signed with a key that is hardware-sealed inside the enclave.
+The cMCP Runtime intercepts every MCP tool call, evaluates it against a Cedar policy bundle, and enforces the result from inside a TEE. The policy bundle hash is measured into the hardware attestation report before any code runs. The audit chain is signed with a key that is hardware-sealed inside the enclave.
The output is a TRACE Claim: a signed, hardware-attested artifact the enterprise hands to an auditor, regulator, or customer instead of a written response. The verifier does not need to trust the operator.
@@ -93,7 +93,7 @@ The output is a TRACE Claim: a signed, hardware-attested artifact the enterprise
Agent
|
v
-cMCP Gateway (TEE boundary) -- the sole MCP endpoint the agent host sees
+cMCP Runtime (TEE boundary) -- the sole MCP endpoint the agent host sees
+-- MCP Protocol Interceptor
| receives every tool call before it reaches the tool
|
@@ -308,7 +308,7 @@ GTM note: For production-bound regulated buyers, the entry point is the proof ga
## 14. Success Metric
-Three enterprise design partners signed on cMCP Gateway by July 15, 2026.
+Three enterprise design partners signed on cMCP Runtime by July 15, 2026.
---
diff --git a/docs/configuration.md b/docs/configuration.md
index 045bfe7d..ad9f5f9b 100644
--- a/docs/configuration.md
+++ b/docs/configuration.md
@@ -1,4 +1,4 @@
-# Configuration Reference
+# Configuration Reference
`cmcp-config.yaml` controls the gateway's attestation provider, policy enforcement behavior, network settings, and file paths. Environment variables override specific fields and control secrets that must not appear in config files.
@@ -27,7 +27,7 @@ attestation:
# warn_only: allow sessions to continue; marks TRACE Claims as stale.
staleness_policy: fail_closed
- # Optional. If set, the gateway verifies the TEE measurement matches
+ # Optional. If set, the runtime verifies the TEE measurement matches
# this value at startup and refuses to start if it does not.
# Format: provider-specific (e.g., hex PCR values for TPM,
# AMD measurement register hex for SEV-SNP).
@@ -42,7 +42,7 @@ policy_bundle_path: policy/
# Must not contain '..' components.
catalog_path: catalog.json
-# Address and port the gateway listens on.
+# Address and port the runtime listens on.
listen_addr: "0.0.0.0:8443"
# Maximum size of a tool response payload in bytes. Responses larger than
@@ -52,7 +52,7 @@ max_response_size_bytes: 2097152
# Interval in seconds between automatic policy bundle reloads.
# 0 (default) disables automatic reload. Changing the policy bundle
-# without restarting the gateway invalidates the attestation measurement.
+# without restarting the runtime invalidates the attestation measurement.
# This field exists for advisory/silent deployments only; do not use in
# enforcing mode without a full enclave restart.
policy_reload_interval_seconds: 0
@@ -68,7 +68,7 @@ policy_reload_interval_seconds: 0
| `enforcement_mode` | string | `enforcing` | Policy enforcement mode. Valid values: `enforcing`, `advisory`, `silent`. |
| `validity_seconds` | integer | `86400` | Attestation report validity period in seconds. Must be a positive integer. At expiry, behavior is controlled by `staleness_policy`. |
| `staleness_policy` | string | `fail_closed` | Action when attestation validity expires. Valid values: `fail_closed` (terminate sessions), `warn_only` (allow sessions, mark claims as stale). |
-| `expected_measurement` | string | none | Optional. Expected TEE measurement value. If set, the gateway verifies the hardware measurement matches this string at startup and exits with a non-zero status if it does not. |
+| `expected_measurement` | string | none | Optional. Expected TEE measurement value. If set, the runtime verifies the hardware measurement matches this string at startup and exits with a non-zero status if it does not. |
### top-level fields
@@ -87,7 +87,7 @@ Environment variables control secrets and mode flags that must not appear in con
| Variable | Description | Overrides |
|----------|-------------|-----------|
| `CMCP_DEV_MODE=1` | Enables software-only attestation. No hardware TEE required. TRACE Claims will show `partially_verified` status. Required when `provider` is `software-only`. | `attestation.provider` (forces software-only) |
-| `CMCP_BEARER_TOKEN` | Optional bearer token for gateway HTTP auth. If set, all requests to the gateway must include `Authorization: Bearer `. If unset, no bearer auth is enforced. | none |
+| `CMCP_BEARER_TOKEN` | Optional bearer token for runtime HTTP auth. If set, all requests to the runtime must include `Authorization: Bearer `. If unset, no bearer auth is enforced. | none |
| `OPAQUE_ATTESTATION_URL` | Enables the Opaque Managed Runtime provider. Must be set to the Opaque attestation service URL. Required when `provider` is `opaque` or `auto` on Opaque infrastructure. | enables `opaque` provider detection |
| `CMCP_CATALOG_HASH` | SHA-256 hash of the approved `catalog.json`. Required in non-dev mode. The gateway fails closed at startup if this is unset and `CMCP_DEV_MODE` is not `1`. Format: `sha256:`. | none (additional startup check) |
@@ -95,8 +95,8 @@ Environment variables control secrets and mode flags that must not appear in con
| Mode | Behavior | Use case |
|------|----------|----------|
-| `enforcing` | Policy denies block the tool call. The gateway returns HTTP 403 and a structured error to the agent. The call is not forwarded to the upstream server. | Production. Default for new deployments. |
-| `advisory` | Policy denies are logged in the audit chain but the call is forwarded. The TRACE Claim records the deny. No tool call is blocked. | Policy testing, migration from existing gateway. Safe for first run with an untuned policy. |
+| `enforcing` | Policy denies block the tool call. The runtime returns HTTP 403 and a structured error to the agent. The call is not forwarded to the upstream server. | Production. Default for new deployments. |
+| `advisory` | Policy denies are logged in the audit chain but the call is forwarded. The TRACE Claim records the deny. No tool call is blocked. | Policy testing, migration from existing runtime. Safe for first run with an untuned policy. |
| `silent` | Policy is evaluated but the result is not acted on and denies are not logged. Observability-only mode. | Measuring policy impact before rollout. Not suitable for any compliance scenario. |
## Minimal working config
diff --git a/docs/quickstart.md b/docs/quickstart.md
index 42c9f0f1..49b05d33 100644
--- a/docs/quickstart.md
+++ b/docs/quickstart.md
@@ -1,4 +1,4 @@
-# Quickstart — cMCP Gateway
+# Quickstart — cMCP Runtime
From zero to first TRACE Claim in under 30 minutes. Uses `CMCP_DEV_MODE=1` so no hardware TEE is required.
@@ -6,7 +6,7 @@ From zero to first TRACE Claim in under 30 minutes. Uses `CMCP_DEV_MODE=1` so no
## What you'll build
-You'll run a cMCP Gateway that intercepts tool calls from a demo agent, enforces a Cedar policy bundle, and produces a signed TRACE Claim at the end of the session. The demo scenario uses a mock `salesforce.contacts` tool. The TRACE Claim records which tools were called, what data classes they touched, and that the policy bundle hash matches what was measured at startup.
+You'll run a cMCP Runtime that intercepts tool calls from a demo agent, enforces a Cedar policy bundle, and produces a signed TRACE Claim at the end of the session. The demo scenario uses a mock `salesforce.contacts` tool. The TRACE Claim records which tools were called, what data classes they touched, and that the policy bundle hash matches what was measured at startup.
---
@@ -186,17 +186,17 @@ print('sha256:' + hashlib.sha256(s.encode()).hexdigest())
"
```
-If you change any field in `approved_definition`, rerun the command and update `definition_hash`. The gateway rejects catalog entries where the hash does not match.
+If you change any field in `approved_definition`, rerun the command and update `definition_hash`. The runtime rejects catalog entries where the hash does not match.
---
-## Start the gateway
+## Start the runtime
```bash
CMCP_DEV_MODE=1 cmcp start --config cmcp-config.yaml
```
-In dev mode the gateway uses a software-only TEE provider (no hardware required). The startup log prints:
+In dev mode the runtime uses a software-only TEE provider (no hardware required). The startup log prints:
```
[cmcp] provider=software-only enforcement_mode=advisory
@@ -231,7 +231,7 @@ curl -X POST http://localhost:8443/mcp \
}'
```
-The gateway intercepts the call, evaluates the Cedar policy (rule 1 matches because `workflow_id == "demo-agent"`), records an audit entry, and forwards to the upstream mock server.
+The runtime intercepts the call, evaluates the Cedar policy (rule 1 matches because `workflow_id == "demo-agent"`), records an audit entry, and forwards to the upstream mock server.
---
@@ -312,7 +312,7 @@ The response is a signed `GatewayClaim`. It looks like:
## Verify
-Use the `cmcp_verify` library to verify the claim without trusting the gateway operator. Replace the hash values with those printed at gateway startup:
+Use the `cmcp_verify` library to verify the claim without trusting the runtime operator. Replace the hash values with those printed at gateway startup:
```python
# verify.py
diff --git a/docs/spec/attestation.md b/docs/spec/attestation.md
index 1f9167aa..631f703e 100644
--- a/docs/spec/attestation.md
+++ b/docs/spec/attestation.md
@@ -1,14 +1,14 @@
# Attestation Specification
**Document status:** Draft v0.1
-**Applies to:** cMCP Gateway, all TEE providers
+**Applies to:** cMCP Runtime, all TEE providers
**Related issues:** #5, #6, #23, #33, #38
---
## Overview
-The cMCP Gateway produces TRACE Claims: signed, hardware-attested proof artifacts that allow a verifier to confirm that a specific set of MCP tool calls was evaluated against a specific policy bundle inside a verified TEE, without trusting the operator. This document is the authoritative specification for how attestation evidence is collected, how the audit chain is constructed, how freshness is enforced, how keys are managed, and how tool catalog integrity is maintained.
+The cMCP Runtime produces TRACE Claims: signed, hardware-attested proof artifacts that allow a verifier to confirm that a specific set of MCP tool calls was evaluated against a specific policy bundle inside a verified TEE, without trusting the operator. This document is the authoritative specification for how attestation evidence is collected, how the audit chain is constructed, how freshness is enforced, how keys are managed, and how tool catalog integrity is maintained.
---
@@ -16,7 +16,7 @@ The cMCP Gateway produces TRACE Claims: signed, hardware-attested proof artifact
### 1.1 Auto-Detection Algorithm
-At gateway startup, the runtime probes for TEE providers in the following fixed order. The first provider whose conditions are satisfied is selected. Only one provider is active per gateway instance.
+At runtime startup, the process probes for TEE providers in the following fixed order. The first provider whose conditions are satisfied is selected. Only one provider is active per runtime instance.
```
probe_order = ["tpm", "sev-snp", "tdx", "opaque"]
@@ -43,8 +43,8 @@ Production deployments must not start if no hardware TEE is available. The `DEVE
#### TPM (Medium Assurance)
Detection conditions (any of):
-- `/dev/tpm0` exists and is readable by the gateway process, OR
-- `/dev/tpmrm0` exists and is readable by the gateway process (resource manager interface), OR
+- `/dev/tpm0` exists and is readable by the runtime process, OR
+- `/dev/tpmrm0` exists and is readable by the runtime process (resource manager interface), OR
- A vTPM device is detected via the TSS2 ESAPI device enumeration call `Esys_GetCapability(TPMS_CAPABILITY_DATA)` returning at least one TPM device handle.
What goes in `attestation_report.measurement`:
@@ -53,14 +53,14 @@ What goes in `attestation_report.measurement`:
measurement = SHA-256(PCR0 || PCR1 || PCR2 || PCR3 || PCR4 || PCR5 || PCR6 || PCR7)
```
-Each PCR value is the raw 32-byte SHA-256 digest read from the TPM. Concatenation is in bank index order (0 through 7), no separators. The result is a 32-byte SHA-256 digest encoded as lowercase hex. The PCR bank used is SHA-256. If the platform only offers a SHA-1 bank, the gateway logs a warning and uses SHA-1 PCR values zero-extended to 32 bytes before hashing; this is noted in `attestation_report.measurement_note: "sha1-bank-fallback"`.
+Each PCR value is the raw 32-byte SHA-256 digest read from the TPM. Concatenation is in bank index order (0 through 7), no separators. The result is a 32-byte SHA-256 digest encoded as lowercase hex. The PCR bank used is SHA-256. If the platform only offers a SHA-1 bank, the runtime logs a warning and uses SHA-1 PCR values zero-extended to 32 bytes before hashing; this is noted in `attestation_report.measurement_note: "sha1-bank-fallback"`.
Quote generation: the gateway calls `TPM2_Quote` with the nonce set to `SHA-256(tee_public_key || session_id)` (see Section 3.3). The quote and its signature are stored in `attestation_report.raw_evidence` (base64-encoded) for verifier use.
#### SEV-SNP (High Assurance)
Detection conditions (all of):
-- `/dev/sev-guest` exists and is readable by the gateway process, AND
+- `/dev/sev-guest` exists and is readable by the runtime process, AND
- The processor vendor string (CPUID leaf 0) equals `"AuthenticAMD"`.
What goes in `attestation_report.measurement`:
@@ -76,7 +76,7 @@ The full SNP report structure is stored in `attestation_report.raw_evidence` (ba
#### TDX (High Assurance)
Detection conditions (all of):
-- `/dev/tdx-guest` exists and is readable by the gateway process, AND
+- `/dev/tdx-guest` exists and is readable by the runtime process, AND
- The processor vendor string (CPUID leaf 0) equals `"GenuineIntel"`.
What goes in `attestation_report.measurement`:
@@ -102,7 +102,7 @@ Detection conditions:
What goes in `attestation_report.measurement`:
-The Opaque Managed Runtime provides a dedicated attestation API. The gateway calls `GET $OPAQUE_RUNTIME_ENDPOINT/v1/attestation` with the nonce `SHA-256(tee_public_key || session_id)` as a query parameter. The response includes an Opaque-specific measurement blob and a signed attestation certificate chain rooted in Opaque's hardware root of trust. The measurement field is set to the `measurement` field from the Opaque attestation response (format defined by the Opaque Runtime SDK; currently a 32-byte SHA-256 encoded as lowercase hex). The full response is stored in `attestation_report.raw_evidence`.
+The Opaque Managed Runtime provides a dedicated attestation API. The runtime calls `GET $OPAQUE_RUNTIME_ENDPOINT/v1/attestation` with the nonce `SHA-256(tee_public_key || session_id)` as a query parameter. The response includes an Opaque-specific measurement blob and a signed attestation certificate chain rooted in Opaque's hardware root of trust. The measurement field is set to the `measurement` field from the Opaque attestation response (format defined by the Opaque Runtime SDK; currently a 32-byte SHA-256 encoded as lowercase hex). The full response is stored in `attestation_report.raw_evidence`.
### 1.3 Software-Only Development Fallback
@@ -121,7 +121,7 @@ When `CMCP_DEV_MODE=1` is set and no hardware TEE is detected:
Rules:
- TRACE Claims with `attestation_assurance: "none"` must not be used for compliance purposes.
-- The gateway logs a prominent warning at startup: `"WARNING: running in software-only mode. TRACE Claims have no hardware attestation and cannot be used for compliance."`.
+- The runtime logs a prominent warning at startup: `"WARNING: running in software-only mode. TRACE Claims have no hardware attestation and cannot be used for compliance."`.
- Signing still occurs (the ephemeral Ed25519 key is generated in normal process memory), but the signature only proves the claim was not tampered with after issuance -- it provides no hardware-backed assurance of the enclave's integrity.
---
@@ -134,7 +134,7 @@ At enclave startup, before accepting any connections:
1. Generate an ephemeral Ed25519 keypair inside the TEE using a CSPRNG seeded from the hardware entropy source (TPM `TPM2_GetRandom`, SEV-SNP `RDRAND` + kernel `/dev/urandom` mix-in, TDX equivalent, or Opaque runtime entropy API).
2. The private key is held only in enclave memory (or equivalent protected region). It is never written to disk, never logged, never exported via any API.
-3. The public key is encoded as a 32-byte Ed25519 public key in base64url (no padding). This value is placed in the `tee_public_key` field of every TRACE Claim issued by this gateway instance.
+3. The public key is encoded as a 32-byte Ed25519 public key in base64url (no padding). This value is placed in the `tee_public_key` field of every TRACE Claim issued by this runtime instance.
4. When the enclave exits (graceful shutdown or crash), the private key is zeroed from memory via a secure-erase routine before the memory region is released.
The attestation report's `report_data` (nonce) is bound to this key, ensuring the hardware-attested report and the signing key are cryptographically linked (see Section 3.3).
@@ -183,7 +183,7 @@ Chain invariants:
- `audit_chain_root` in the TRACE Claim = `entry_hash` of the first entry.
- `audit_chain_tip` in the TRACE Claim = `entry_hash` of the most recent entry at the time the TRACE Claim is generated.
- The chain is append-only. No entry may be modified or deleted after it is written.
-- The chain lives entirely inside the enclave's memory (or encrypted persistent storage for long-running gateways). No external process can append to or modify the chain.
+- The chain lives entirely inside the enclave's memory (or encrypted persistent storage for long-running runtime instances). No external process can append to or modify the chain.
A verifier reconstructing the chain recomputes each `entry_hash` from the entry body and checks that each `prev_entry_hash` equals the `entry_hash` of the preceding entry, confirming append-only integrity across the full session.
@@ -191,10 +191,10 @@ A verifier reconstructing the chain recomputes each `entry_hash` from the entry
Audit logs are exported as a signed bundle to prevent selective disclosure:
-1. Verifier sends a signed API request to the gateway's export endpoint: `POST /v1/audit/export` with a body containing `{"session_id": "", "verifier_nonce": ""}`. The request must be signed with a verifier key whose public key is pre-configured in the gateway's policy bundle.
-2. The gateway assembles the full ordered array of all audit entries for the session.
-3. The gateway computes `bundle_hash = SHA-256(canonical_json(entries_array))`.
-4. The gateway signs `bundle_hash || verifier_nonce` with the enclave's Ed25519 private key.
+1. Verifier sends a signed API request to the runtime's export endpoint: `POST /v1/audit/export` with a body containing `{"session_id": "", "verifier_nonce": ""}`. The request must be signed with a verifier key whose public key is pre-configured in the runtime's policy bundle.
+2. The runtime assembles the full ordered array of all audit entries for the session.
+3. The runtime computes `bundle_hash = SHA-256(canonical_json(entries_array))`.
+4. The runtime signs `bundle_hash || verifier_nonce` with the enclave's Ed25519 private key.
5. The response is:
```json
@@ -230,7 +230,7 @@ The TRACE Claim includes:
}
```
-Default: `attestation_validity_seconds = 86400` (24 hours). Configurable via `gateway.yaml`:
+Default: `attestation_validity_seconds = 86400` (24 hours). Configurable via `cmcp-config.yaml`:
```yaml
attestation:
@@ -250,7 +250,7 @@ If this check fails, the TRACE Claim is considered stale. Verifiers must reject
Attestation refresh without service interruption:
1. While the enclave is running, call the TEE's attestation API again with a fresh timestamp and the same nonce (`SHA-256(tee_public_key || session_id)`).
-2. Replace `attestation_report` in the gateway's in-memory state with the new report.
+2. Replace `attestation_report` in the runtime's in-memory state with the new report.
3. Update `attestation_generated_at` to the current UTC timestamp.
4. All subsequent TRACE Claims use the new `attestation_report` and new `attestation_generated_at`.
5. TRACE Claims already issued during the current session retain their original `attestation_generated_at`. They are valid for their own validity window and are not retroactively stale.
@@ -263,7 +263,7 @@ attestation:
max_session_duration: 86400 # equals validity_seconds by default
```
-Sessions cannot outlive the attestation. If a session reaches `max_session_duration`, the gateway closes it and requires the agent to reconnect. On reconnect, the agent receives a TRACE Claim with a fresh attestation.
+Sessions cannot outlive the attestation. If a session reaches `max_session_duration`, the runtime closes it and requires the agent to reconnect. On reconnect, the agent receives a TRACE Claim with a fresh attestation.
### 3.3 Replay Prevention
@@ -293,7 +293,7 @@ A TRACE Claim replayed from a different session (different `session_id`) or from
### 4.1 Phase 1: Ephemeral Keys
-In Phase 1, the gateway uses a single ephemeral Ed25519 keypair per enclave instance. Properties:
+In Phase 1, the runtime uses a single ephemeral Ed25519 keypair per enclave instance. Properties:
- Generated at enclave startup (see Section 2.1).
- Exists only in enclave memory. Never exported, never persisted.
@@ -310,7 +310,7 @@ Because the public key is embedded in the claim and attested by the hardware rep
### 4.2 Phase 2: Persistent Keys (Future)
-For use cases requiring long-lived keys (e.g., participation in a key transparency log, or gateway restarts without breaking verifier trust):
+For use cases requiring long-lived keys (e.g., participation in a key transparency log, or runtime restarts without breaking verifier trust):
- At first startup, generate an Ed25519 keypair and seal the private key to the TEE's measurement using the TEE's sealing API (TPM `TPM2_Create` with a parent key bound to PCRs; SEV-SNP sealing via a policy-bound key; TDX sealing via TD-bound key derivation; Opaque sealing via Opaque's key management API).
- The sealed key blob is stored on disk. On restart, the enclave unseals the key. Unsealing succeeds only if the enclave's current measurement matches the measurement policy used when sealing.
@@ -336,7 +336,7 @@ There is no online revocation mechanism for Phase 1 keys. Revocation is handled
### 5.1 Catalog Format
-The tool catalog is a JSON document versioned in the repository alongside the gateway configuration. It defines the set of approved tools and their expected definitions.
+The tool catalog is a JSON document versioned in the repository alongside the runtime configuration. It defines the set of approved tools and their expected definitions.
Top-level structure:
@@ -391,7 +391,7 @@ catalog_hash = lowercase_hex(SHA-256(canonical_json(sorted_entries)))
Only the `entries` array (sorted) is hashed, not the `catalog_version` or `updated_at` fields. This ensures the catalog hash is stable across metadata-only updates.
-At enclave startup, the gateway:
+At enclave startup, the runtime:
1. Loads the catalog document from the configured path.
2. Computes `catalog_hash` as above.
3. Stores the hash in the enclave's immutable measurement context (or records it for inclusion in every TRACE Claim).
@@ -399,7 +399,7 @@ At enclave startup, the gateway:
### 5.3 Delta Detection
-When the gateway receives a `notifications/tools/list_changed` notification from an upstream MCP server:
+When the runtime receives a `notifications/tools/list_changed` notification from an upstream MCP server:
```
procedure handle_tools_list_changed(server_identity):
@@ -446,7 +446,7 @@ The catalog does not support hot-reload in Phase 1. Updates require:
2. Recompute `definition_hash` for any modified `approved_definition`.
3. Commit the updated catalog to version control. This creates an auditable record of who approved the change and when.
4. Compute the new `catalog_hash` locally and record it in the commit message or PR description for pre-deployment verification.
-5. Deploy the new gateway configuration. This requires an enclave restart.
+5. Deploy the new runtime configuration. This requires an enclave restart.
6. On restart, the new enclave measures the new catalog hash. Subsequent TRACE Claims will contain the new `tool_catalog.hash`.
7. Verify: after startup, call `GET /v1/status` which returns the active `catalog_hash`. Confirm it matches the expected value from step 4.
diff --git a/docs/spec/call-graph.md b/docs/spec/call-graph.md
index 535b6162..b1e040a2 100644
--- a/docs/spec/call-graph.md
+++ b/docs/spec/call-graph.md
@@ -1,4 +1,4 @@
-# Call Graph Tracking
+# Call Graph Tracking
Status: Draft v0.1 | Closes #35 | Related: session-policy.md, cedar-policy.md
@@ -6,18 +6,18 @@ Status: Draft v0.1 | Closes #35 | Related: session-policy.md, cedar-policy.md
Individual call authorization is insufficient for cross-system compliance boundary enforcement (P1.3). A session may issue a sequence of tool calls where each individual call is individually authorized, yet the combination crosses a compliance boundary. For example: call A retrieves PHI from an EHR tool (authorized for the principal), and call B posts to an external webhook (also authorized for the principal in isolation). Neither call is individually impermissible, but together they represent an unauthorized export of PHI across a regulatory boundary.
-The gateway tracks a per-session call log inside the enclave to detect and enforce against these cross-boundary patterns. This document specifies how that tracking works, what the gateway can and cannot observe, and what the resulting enforcement guarantees actually mean.
+The runtime tracks a per-session call log inside the enclave to detect and enforce against these cross-boundary patterns. This document specifies how that tracking works, what the runtime can and cannot observe, and what the resulting enforcement guarantees actually mean.
-## The Gateway's Observability Limit (Critical)
+## The Runtime's Observability Limit (Critical)
-The gateway sits at the MCP transport boundary. It can observe:
+The runtime sits at the MCP transport boundary. It can observe:
- Which tool calls are made (tool name, server, arguments)
- Which responses are returned to the agent runtime
- The sequence and timing of calls and responses within a session
- The compliance metadata attached to each tool in the catalog
-The gateway **cannot** observe:
+The runtime **cannot** observe:
- Whether the agent included a specific response in its next context window
- Whether the agent reformulated, summarized, or discarded a response before issuing a subsequent call
@@ -25,19 +25,19 @@ The gateway **cannot** observe:
- The agent's internal reasoning about which data influenced which subsequent call
- The contents of the agent's context window at any given moment
-This is not a gap that can be closed by the gateway alone. The gateway has no privileged access to the agent runtime, the model's context, or the orchestration layer's memory management. Agents may truncate context, use summarization, apply sliding windows, or selectively include only parts of prior responses. These are design choices of the agent system, not observable behaviors at the MCP transport layer.
+This is not a gap that can be closed by the runtime alone. The runtime has no privileged access to the agent process, the model's context, or the orchestration layer's memory management. Agents may truncate context, use summarization, apply sliding windows, or selectively include only parts of prior responses. These are design choices of the agent system, not observable behaviors at the MCP transport layer.
-This means the call graph the gateway maintains is an **approximation based on temporal adjacency**, not true data provenance. Any implementation claiming to track "which data from tool A flowed into tool B's request" is making an inference, not an observation. This distinction has material consequences for compliance claims: a TRACE Claim generated from gateway-observable data cannot assert true data lineage, only temporal co-occurrence within a session.
+This means the call graph the runtime maintains is an **approximation based on temporal adjacency**, not true data provenance. Any implementation claiming to track "which data from tool A flowed into tool B's request" is making an inference, not an observation. This distinction has material consequences for compliance claims: a TRACE Claim generated from runtime-observable data cannot assert true data lineage, only temporal co-occurrence within a session.
## Tag-Propagation Model (Phase 1)
-Instead of attempting to track data flow (which is not observable by the gateway), Phase 1 uses a **tag-propagation model**: sensitivity tags are associated with tool responses and accumulated conservatively at the session level based on observable events.
+Instead of attempting to track data flow (which is not observable by the runtime), Phase 1 uses a **tag-propagation model**: sensitivity tags are associated with tool responses and accumulated conservatively at the session level based on observable events.
-The governing principle is conservatism. The gateway cannot know whether a high-sensitivity response influenced a subsequent call, so it assumes that it did. This may produce false positives (blocking a call that would not actually use sensitive data), but it will not produce false negatives (allowing a call that does use sensitive data). For regulated data categories, false negatives are the unacceptable failure mode.
+The governing principle is conservatism. The runtime cannot know whether a high-sensitivity response influenced a subsequent call, so it assumes that it did. This may produce false positives (blocking a call that would not actually use sensitive data), but it will not produce false negatives (allowing a call that does use sensitive data). For regulated data categories, false negatives are the unacceptable failure mode.
### What Gets Tagged
-When the gateway receives a tool response, it classifies the response and assigns sensitivity tags based on three sources, evaluated in order:
+When the runtime receives a tool response, it classifies the response and assigns sensitivity tags based on three sources, evaluated in order:
1. **The tool's catalog entry** (`compliance_domain`, `sensitivity_level`) — known at call time, before the response arrives
2. **Cedar policy annotations on the tool** (for example, `"this tool always returns PHI"`) — known at call time
@@ -55,7 +55,7 @@ public < pii < confidential < trade_secret
`hipaa_phi`, `mnpi`, and `trade_secret` are terminal high-sensitivity tags. Once any of these is present in `session_max_sensitivity`, that status persists for the session lifetime unless an explicit session reset is issued via the API.
-### What the Gateway Stores
+### What the Runtime Stores
Per-session call log (maintained inside the enclave as in-memory working state; this is distinct from the immutable audit chain entry, which is written once per call at decision time):
@@ -115,7 +115,7 @@ The TRACE Claim metadata **must** document this distinction explicitly. See the
## Cross-System Compliance Boundary Policy
-Cedar policy that enforces cross-boundary restrictions using `session_max_sensitivity` (which the gateway observes directly):
+Cedar policy that enforces cross-boundary restrictions using `session_max_sensitivity` (which the runtime observes directly):
```cedar
forbid(principal, action == Action::"call_tool", resource)
@@ -128,7 +128,7 @@ when {
This correctly expresses: "if any call in this session has received a PHI-tagged response, do not allow calls to external destinations that are not covered by a BAA."
-It does **not** express: "data from this specific PHI call flows to this specific external destination." That statement cannot be made from gateway-observable data. The Cedar policy is intentionally written around what the gateway knows.
+It does **not** express: "data from this specific PHI call flows to this specific external destination." That statement cannot be made from runtime-observable data. The Cedar policy is intentionally written around what the gateway knows.
Additional cross-boundary policies follow the same pattern:
@@ -154,7 +154,7 @@ Add to the `call_summary` block of the TRACE Claim:
```json
"call_graph_summary": {
"tracking_model": "temporal_adjacency_v1",
- "provenance_disclaimer": "Edges represent temporal adjacency within session, not observed data flow. Gateway cannot verify agent context window contents.",
+ "provenance_disclaimer": "Edges represent temporal adjacency within session, not observed data flow. Runtime cannot verify agent context window contents.",
"session_max_sensitivity": "hipaa_phi",
"compliance_domains_touched": ["hipaa_phi", "external"],
"high_sensitivity_call_ids": ["uuid-of-phi-call"],
@@ -184,13 +184,13 @@ The `provenance_disclaimer` field is required in every TRACE Claim that includes
Phase 1 conservatism is the correct starting point but may produce unacceptable false-positive rates in agents that routinely retrieve high-sensitivity data and interact with many downstream tools, where most downstream calls do not actually use the sensitive data.
-Phase 2 addresses this by adding agent-side SDK hooks that report context window contents at call time. With agent cooperation, the gateway could receive a manifest of which prior call IDs are represented in the current context window when a new call is issued. This would enable true data provenance edges rather than temporal adjacency approximations.
+Phase 2 addresses this by adding agent-side SDK hooks that report context window contents at call time. With agent cooperation, the runtime could receive a manifest of which prior call IDs are represented in the current context window when a new call is issued. This would enable true data provenance edges rather than temporal adjacency approximations.
Phase 2 is out of scope for the current implementation. It requires:
1. A defined SDK interface for agent runtimes to report context state
-2. An attestation model for the gateway to verify that context reports are not fabricated
-3. Revised Cedar policy semantics that distinguish "agent reports this response is in context" from "gateway inferred this response might be in context"
+2. An attestation model for the runtime to verify that context reports are not fabricated
+3. Revised Cedar policy semantics that distinguish "agent reports this response is in context" from "runtime inferred this response might be in context"
Until Phase 2 is implemented, all call graph tracking is temporal adjacency. The TRACE Claim format defined above accommodates both models via the `tracking_model` field.
diff --git a/docs/spec/cedar-policy.md b/docs/spec/cedar-policy.md
index 213079f5..03d82ebe 100644
--- a/docs/spec/cedar-policy.md
+++ b/docs/spec/cedar-policy.md
@@ -1,4 +1,4 @@
-# Cedar Policy Specification
+# Cedar Policy Specification
---
Status: Draft v0.1
@@ -6,7 +6,7 @@ Last updated: 2026-06-04
Stability: Unstable — expect breaking changes before v1.0
---
-This document specifies the Cedar policy bundle format, policy expression examples, enforcement modes, evaluation decision flow, and related governance features for the cMCP Gateway.
+This document specifies the Cedar policy bundle format, policy expression examples, enforcement modes, evaluation decision flow, and related governance features for the cMCP Runtime.
---
@@ -170,9 +170,9 @@ Enforcement mode is set in the deployment configuration, bound into the attestat
| Mode | Cedar deny behavior | Audit entry |
|------|--------------------|-|
-| `enforcing` | Gateway rejects the call, returns a structured error to the agent | Logged with `decision=deny` |
-| `advisory` | Gateway allows the call, forwards to upstream | Logged with `decision=deny_advisory` (would have been denied in enforcing mode) |
-| `silent` | Gateway allows the call, forwards to upstream | Only a basic call log; no audit decision entry |
+| `enforcing` | Runtime rejects the call, returns a structured error to the agent | Logged with `decision=deny` |
+| `advisory` | Runtime allows the call, forwards to upstream | Logged with `decision=deny_advisory` (would have been denied in enforcing mode) |
+| `silent` | Runtime allows the call, forwards to upstream | Only a basic call log; no audit decision entry |
**Structured error (enforcing mode):**
@@ -182,7 +182,7 @@ Enforcement mode is set in the deployment configuration, bound into the attestat
"tool_name": "",
"call_id": "",
"policy_bundle_version": "",
- "message": "Tool call denied by gateway policy."
+ "message": "Tool call denied by runtime policy."
}
```
@@ -232,7 +232,7 @@ The error does not include the matched rule name or policy text, to avoid leakin
11. Return (possibly redacted) response to agent
```
-Latency budget: Cedar evaluation target is under 1 ms for bundles up to 500 policy rules. The gateway measures and logs `latency_us` for each evaluation to support SLA monitoring.
+Latency budget: Cedar evaluation target is under 1 ms for bundles up to 500 policy rules. The runtime measures and logs `latency_us` for each evaluation to support SLA monitoring.
---
@@ -269,7 +269,7 @@ Workflow identity is established via session metadata. The agent includes a `wor
- HTTP transport: `X-MCP-Workflow-ID` header
- Session configuration: `workflow_id` field in the session init payload
-If `workflow_id` is absent, the gateway defaults to `workflow_id = "default"`. The default workflow policy should be restrictive (allowlist only widely-approved tools).
+If `workflow_id` is absent, the runtime defaults to `workflow_id = "default"`. The default workflow policy should be restrictive (allowlist only widely-approved tools).
### Evaluation Order
@@ -298,15 +298,15 @@ This allows Cedar policies to reference `context.workflow_allowed_tools` as deri
| Phase | Behavior |
|-------|----------|
| Phase 1 | Static workflow policies committed in the Cedar bundle. The `workflow_id` is trusted as declared by the agent. |
-| Phase 2 | Dynamic workflow attestation: the agent cryptographically declares its current workflow; the gateway verifies the declaration before evaluating workflow-scoped policies. |
+| Phase 2 | Dynamic workflow attestation: the agent cryptographically declares its current workflow; the runtime verifies the declaration before evaluating workflow-scoped policies. |
---
-## Section 7 — Gateway as Sole MCP Endpoint (closes #39)
+## Section 7 — Runtime as Sole MCP Endpoint (closes #39)
### Agent Host Configuration
-The agent's MCP client is configured with exactly one MCP server URL: the gateway's URL. All upstream servers are invisible to the agent; the gateway handles routing internally.
+The agent's MCP client is configured with exactly one MCP server URL: the runtime's URL. All upstream servers are invisible to the agent; the runtime handles routing internally.
Example `claude_desktop_config.json`:
@@ -321,11 +321,11 @@ Example `claude_desktop_config.json`:
}
```
-The agent never learns the upstream server URLs. From the agent's perspective, there is one MCP server. This prevents agents from bypassing the gateway by connecting directly to upstream servers.
+The agent never learns the upstream server URLs. From the agent's perspective, there is one MCP server. This prevents agents from bypassing the runtime by connecting directly to upstream servers.
### Adding a New Upstream Server
-To add an upstream MCP server to the gateway catalog:
+To add an upstream MCP server to the runtime catalog:
1. Add a catalog entry to `catalog.json` in version control (see `tool-identity.md` for schema).
2. Recompute the policy bundle hash (the catalog hash is a separate field in the TRACE Claim: `tool_catalog.hash`).
@@ -336,7 +336,7 @@ The new server is not reachable until the enclave restarts with the updated cata
### Emergency Access (Break-Glass)
-If an unauthorized server must be accessed urgently without an enclave restart, the gateway supports a break-glass mode. Break-glass adds the server to a temporary exception list for the current enclave session.
+If an unauthorized server must be accessed urgently without an enclave restart, the runtime supports a break-glass mode. Break-glass adds the server to a temporary exception list for the current enclave session.
Break-glass use is visible in the TRACE Claim:
diff --git a/docs/spec/component-model.md b/docs/spec/component-model.md
index 09107e17..02ebd8aa 100644
--- a/docs/spec/component-model.md
+++ b/docs/spec/component-model.md
@@ -23,9 +23,9 @@ Closes #43.
**Trust level**: Software-rooted. The agent host identity is established by TLS certificates or SPIFFE SVIDs provisioned at deploy time, not by hardware measurement. Its behavior is not isolated from the underlying OS.
**Responsibilities**:
-- Provisions MCP client(s) with the gateway endpoint.
-- Holds the SPIFFE SVID (issued by SPIRE, conditioned on gateway attestation -- see transport spec).
-- Does not connect directly to any MCP server. All MCP traffic goes through the gateway.
+- Provisions MCP client(s) with the runtime endpoint.
+- Holds the SPIFFE SVID (issued by SPIRE, conditioned on runtime attestation -- see transport spec).
+- Does not connect directly to any MCP server. All MCP traffic goes through the runtime.
---
@@ -35,7 +35,7 @@ Closes #43.
**Owned by**: Model provider (for hosted models) or enterprise (for self-hosted models).
-**Trust level**: Untrusted from the gateway perspective. Tool choices and payloads are outputs of a probabilistic model, not deterministic code. The gateway assumes the agent may produce any tool call at any time, including calls that violate policy. The gateway enforces policy on every call regardless of agent intent.
+**Trust level**: Untrusted from the runtime's perspective. Tool choices and payloads are outputs of a probabilistic model, not deterministic code. The runtime assumes the agent may produce any tool call at any time, including calls that violate policy. The runtime enforces policy on every call regardless of agent intent.
**Note**: The agent being "untrusted" does not mean it is assumed to be malicious. It means the gateway does not rely on the agent good behavior as a security control.
@@ -49,17 +49,17 @@ Closes #43.
**Trust level**: Software-rooted. The client is a library in the agent host process; it has the same trust level as the agent host.
-**Phase 1 configuration**: The MCP client is configured with a single endpoint -- the cMCP Gateway. It does not maintain connections to individual MCP servers. The gateway presents itself as a single MCP server to the client; internally it routes calls to the appropriate upstream MCP server.
+**Phase 1 configuration**: The MCP client is configured with a single endpoint -- the cMCP Runtime. It does not maintain connections to individual MCP servers. The runtime presents itself as a single MCP server to the client; internally it routes calls to the appropriate upstream MCP server.
---
-### cMCP Gateway
+### cMCP Runtime
-**Definition**: The governance proxy. Every MCP tool call from the agent passes through the gateway. The gateway evaluates each call against a Cedar policy bundle, produces a TRACE Claim, and forwards allowed calls to the upstream MCP server.
+**Definition**: The governance proxy. Every MCP tool call from the agent passes through the runtime. The runtime evaluates each call against a Cedar policy bundle, produces a TRACE Claim, and forwards allowed calls to the upstream MCP server.
**Owned by**: Enterprise deployer (Phase 1) or SaaS vendor (Phase 2, provider-side).
-**Trust level**: Hardware-rooted. The gateway runs inside a TEE (TPM, SEV-SNP, TDX, or Opaque). Its identity is a SPIFFE SVID issued only after TEE attestation succeeds. Its signing key is sealed to the TEE and never exported. Its behavior is covered by the hardware measurement.
+**Trust level**: Hardware-rooted. The runtime runs inside a TEE (TPM, SEV-SNP, TDX, or Opaque). Its identity is a SPIFFE SVID issued only after TEE attestation succeeds. Its signing key is sealed to the TEE and never exported. Its behavior is covered by the hardware measurement.
**Responsibilities**:
- Terminates mTLS connections from agent hosts (verifying SPIFFE SVIDs).
@@ -78,7 +78,7 @@ Closes #43.
**Trust level**:
- **Phase 1**: Software-rooted. The MCP server runs outside the TEE. Its responses are received by the gateway but are not hardware-attested. The gateway trusts that the server returns what it claims to return, but this is not verifiable beyond TLS.
-- **Phase 2**: Hardware-rooted. The SaaS vendor runs the MCP server inside its own TEE. The gateway can verify the server attestation report before routing calls to it. Both ends of the call are hardware-attested.
+- **Phase 2**: Hardware-rooted. The SaaS vendor runs the MCP server inside its own TEE. The runtime can verify the server attestation report before routing calls to it. Both ends of the call are hardware-attested.
---
@@ -94,7 +94,7 @@ Closes #43.
## Trust Boundary Diagrams
-### Phase 1: Gateway Inside TEE
+### Phase 1: Runtime Inside TEE
```
+-------------------------------------------------------------+
@@ -112,7 +112,7 @@ Closes #43.
# TEE BOUNDARY (Phase 1) #
# #
# +-----------------------+ #
- # | cMCP Gateway | #
+ # | cMCP Runtime | #
# | [hardware-rooted] | #
# | | #
# | Cedar policy engine | #
@@ -133,7 +133,7 @@ Closes #43.
+---------------------------------+
Verification points:
- [A] Agent-side: SPIFFE SVID confirms gateway identity before sending any call
+ [A] Agent-side: SPIFFE SVID confirms runtime identity before sending any call
[B] External auditor: verifies TRACE Claim signature against TEE public key
and checks attestation report against known-good measurement
```
@@ -147,8 +147,8 @@ Verification points:
+----------------------------------------------+--------------+
|
#========================+================#
- # TEE BOUNDARY -- Gateway #
- # cMCP Gateway [hardware-rooted] #
+ # TEE BOUNDARY -- Runtime #
+ # cMCP Runtime [hardware-rooted] #
#========================+================#
| mTLS (mutual SPIFFE SVIDs)
#========================+================#
@@ -173,7 +173,7 @@ The TRACE Claim can include the server attestation measurement.
| Agent Host | Software-rooted | Software-rooted |
| Agent (LLM + loop) | Untrusted | Untrusted |
| MCP Client | Software-rooted | Software-rooted |
-| cMCP Gateway | **Hardware-rooted** (inside TEE) | **Hardware-rooted** (inside TEE) |
+| cMCP Runtime | **Hardware-rooted** (inside TEE) | **Hardware-rooted** (inside TEE) |
| MCP Server (first-party) | Software-rooted | **Hardware-rooted** (inside TEE) |
| MCP Server (third-party SaaS) | Software-rooted | **Hardware-rooted** (vendor TEE) |
| MCP Server (local/stdio) | Out of scope | Out of scope |
@@ -186,22 +186,22 @@ The TRACE Claim can include the server attestation measurement.
| Caller | Callee | Protocol | Authentication Method |
|--------|--------|----------|-----------------------|
| Agent | MCP Client | In-process API | N/A (same process) |
-| MCP Client | cMCP Gateway | JSON-RPC 2.0 over HTTP/SSE | mTLS with SPIFFE SVID |
-| cMCP Gateway | MCP Server | JSON-RPC 2.0 over HTTP/SSE | mTLS with TLS client cert (Phase 1); mTLS with SPIFFE SVID (Phase 2) |
+| MCP Client | cMCP Runtime | JSON-RPC 2.0 over HTTP/SSE | mTLS with SPIFFE SVID |
+| cMCP Runtime | MCP Server | JSON-RPC 2.0 over HTTP/SSE | mTLS with TLS client cert (Phase 1); mTLS with SPIFFE SVID (Phase 2) |
| MCP Server | Backend System | REST, SQL, gRPC, or other | Backend-native credentials (API key, IAM role, DB password) |
-| External Auditor | TRACE Claim | Offline verification | TEE public key (from attestation report); no live connection to gateway required |
-| SPIRE | cMCP Gateway | SPIFFE workload API | TEE attestation (node attestation plugin) |
+| External Auditor | TRACE Claim | Offline verification | TEE public key (from attestation report); no live connection to runtime required |
+| SPIRE | cMCP Runtime | SPIFFE workload API | TEE attestation (node attestation plugin) |
---
## Verification Points
-**Agent-side verification**: Before routing any tool call, the agent MCP client verifies the gateway TLS certificate against the expected SPIFFE SVID. This confirms the agent is talking to an attested gateway, not an impersonator. The SPIFFE SVID is the agent-side trust anchor.
+**Agent-side verification**: Before routing any tool call, the agent MCP client verifies the runtime TLS certificate against the expected SPIFFE SVID. This confirms the agent is talking to an attested runtime, not an impersonator. The SPIFFE SVID is the agent-side trust anchor.
**External auditor verification**: The auditor receives TRACE Claims (out-of-band, from a log store or delivered by the enterprise). The auditor verifies:
1. The TRACE Claim signature against the TEE public key embedded in the claim.
2. The TEE public key against the attestation report (the key is bound to the TEE measurement).
-3. The attestation report against the known-good measurement for the gateway version (obtained from the build pipeline or a public transparency log).
+3. The attestation report against the known-good measurement for the runtime version (obtained from the build pipeline or a public transparency log).
4. The policy bundle hash against the expected hash for the declared policy version.
-This verification requires no live connection to the gateway. It can be done weeks or months after the fact, satisfying P3.1 (regulatory proof requests) and P3.2 (customer pre-renewal questionnaires).
+This verification requires no live connection to the runtime. It can be done weeks or months after the fact, satisfying P3.1 (regulatory proof requests) and P3.2 (customer pre-renewal questionnaires).
diff --git a/docs/spec/error-codes.md b/docs/spec/error-codes.md
index c9d4cb62..fd71100b 100644
--- a/docs/spec/error-codes.md
+++ b/docs/spec/error-codes.md
@@ -1,8 +1,8 @@
-# Error Code Registry
+# Error Code Registry
-This is the normative registry for all error codes used across the cMCP Gateway. Every error code MUST be registered here before it is referenced in code, configuration, or other spec documents. Implementations MUST NOT emit error codes that do not appear in this registry.
+This is the normative registry for all error codes used across the cMCP Runtime. Every error code MUST be registered here before it is referenced in code, configuration, or other spec documents. Implementations MUST NOT emit error codes that do not appear in this registry.
-## Gateway Errors
+## Runtime Errors
| error_code | HTTP status | log level | description | spec reference |
|---|---|---|---|---|
@@ -39,4 +39,4 @@ The following error codes are defined and documented in [verification-library.md
| `CHAIN_BROKEN` |
| `CLAIM_MALFORMED` |
-> Note: `POLICY_HASH_MISMATCH`, `CATALOG_HASH_MISMATCH`, and `ATTESTATION_STALE` appear in both tables. The Gateway emits them during startup or request handling; the verification library emits them during offline or client-side verification. The semantics are consistent across both contexts.
+> Note: `POLICY_HASH_MISMATCH`, `CATALOG_HASH_MISMATCH`, and `ATTESTATION_STALE` appear in both tables. The Runtime emits them during startup or request handling; the verification library emits them during offline or client-side verification. The semantics are consistent across both contexts.
diff --git a/docs/spec/failure-modes.md b/docs/spec/failure-modes.md
index 2f1f73bd..ea7a5e55 100644
--- a/docs/spec/failure-modes.md
+++ b/docs/spec/failure-modes.md
@@ -6,7 +6,7 @@ Last updated: 2026-06-04
Stability: Unstable — expect breaking changes before v1.0
---
-Documents exact gateway behavior for every failure scenario.
+Documents exact runtime behavior for every failure scenario.
Closes #22.
@@ -16,23 +16,23 @@ Closes #22.
| Failure | Default Behavior | Configurable? | TRACE Claim Status | Log Format |
|---------|-----------------|---------------|-------------------|------------|
-| Attestation failure at startup | Fail-closed. Gateway does not start. No traffic processed. | No | Not produced | `FATAL attestation_failure` + provider + error code |
+| Attestation failure at startup | Fail-closed. Runtime does not start. No traffic processed. | No | Not produced | `FATAL attestation_failure` + provider + error code |
| Attestation staleness mid-session | Fail-closed. Active sessions terminated. | Yes (see FM-2) | `attestation_stale: true` on claims produced at or after deadline | `WARN attestation_stale` + session_id + expiry_utc |
| TEE fault mid-invocation | Fail-closed on in-flight call. Structured error returned to agent. Session continues if TEE recovers. | No | `status: fault` | `ERROR tee_fault` + call_id + timestamp |
-| Policy bundle hash mismatch at startup | Fail-closed. Gateway does not start. | No | Not produced | `FATAL policy_hash_mismatch` + expected_hash + actual_hash |
+| Policy bundle hash mismatch at startup | Fail-closed. Runtime does not start. | No | Not produced | `FATAL policy_hash_mismatch` + expected_hash + actual_hash |
| MCP protocol parse failure | Fail-closed on the specific call. Structured error returned. Session continues. | No | `status: parse_error` | `WARN parse_failure` + call_id + payload_hash |
---
## FM-1: Attestation Failure at Startup
-**Trigger**: The TEE cannot produce a valid attestation report at gateway startup. Causes include: TPM not present or disabled in firmware, SEV-SNP or TDX not enabled on the host, firmware version not matching a known-good measurement, or the attestation service is unreachable.
+**Trigger**: The TEE cannot produce a valid attestation report at runtime startup. Causes include: TPM not present or disabled in firmware, SEV-SNP or TDX not enabled on the host, firmware version not matching a known-good measurement, or the attestation service is unreachable.
-**Decision**: Fail-closed. The gateway does not start. No MCP traffic is processed. No TRACE Claims are produced (there is no attested identity to sign with).
+**Decision**: Fail-closed. The runtime does not start. No MCP traffic is processed. No TRACE Claims are produced (there is no attested identity to sign with).
**Behavior**:
-1. Gateway startup sequence attempts attestation as the first step, before binding any network port.
-2. If attestation fails, the gateway writes a structured log entry and exits with a non-zero status code.
+1. Runtime startup sequence attempts attestation as the first step, before binding any network port.
+2. If attestation fails, the runtime writes a structured log entry and exits with a non-zero status code.
3. The orchestrator (Kubernetes, systemd, ECS) observes the non-zero exit and does not route traffic to the pod/service.
**Log entry format**:
@@ -44,12 +44,12 @@ Closes #22.
"tee_provider": "sev-snp",
"error_code": "ATTESTATION_REPORT_UNAVAILABLE",
"error_detail": "AMD PSP did not return a report within 5000ms",
- "gateway_version": "0.3.0",
+ "cmcp_version": "0.3.0",
"action": "startup_aborted"
}
```
-**Operator notification**: The orchestration platform health check fails (no process listening on the health port). Alerting on pod restart loops or task failure is the operator responsibility. The gateway does not attempt to send an outbound notification from a failed-attestation state, as there is no attested channel to send it on.
+**Operator notification**: The orchestration platform health check fails (no process listening on the health port). Alerting on pod restart loops or task failure is the operator responsibility. The runtime does not attempt to send an outbound notification from a failed-attestation state, as there is no attested channel to send it on.
---
@@ -62,10 +62,10 @@ Closes #22.
**Configurable option**: `attestation_staleness_policy: warn_only` allows sessions to continue past the validity deadline. This is not recommended for production. TRACE Claims produced after the deadline are marked `attestation_stale: true` to alert downstream verifiers.
**Behavior (default, fail-closed)**:
-1. Gateway tracks the attestation validity deadline per session.
-2. At the deadline, the gateway closes the session: sends a structured close notification to the agent, writes a log entry, and marks the session closed in the audit chain.
+1. Runtime tracks the attestation validity deadline per session.
+2. At the deadline, the runtime closes the session: sends a structured close notification to the agent, writes a log entry, and marks the session closed in the audit chain.
3. In-flight tool calls at the moment of termination are treated as FM-3 (TEE fault mid-invocation): fail-closed, structured error returned.
-4. No new sessions are accepted until attestation is renewed (gateway restarts with a fresh report, or a re-attestation flow completes if supported by the provider).
+4. No new sessions are accepted until attestation is renewed (runtime restarts with a fresh report, or a re-attestation flow completes if supported by the provider).
**TRACE Claim field** (when `warn_only` is configured):
```json
@@ -95,15 +95,15 @@ Closes #22.
## FM-3: TEE Fault Mid-Invocation
-**Trigger**: The TEE process (the gateway enclave context) crashes, becomes unresponsive, or returns an internal fault during an active tool call. This covers: enclave exception, out-of-memory inside the TEE, watchdog timeout, or unhandled panic in the gateway process.
+**Trigger**: The TEE process (the runtime enclave context) crashes, becomes unresponsive, or returns an internal fault during an active tool call. This covers: enclave exception, out-of-memory inside the TEE, watchdog timeout, or unhandled panic in the gateway process.
-**Decision**: Fail-closed on the in-flight call. The agent receives a structured error, not the tool response (which was never obtained or cannot be trusted). The audit chain records the fault. If the TEE recovers (e.g., the gateway process restarts and re-attests), subsequent calls in a new session may proceed.
+**Decision**: Fail-closed on the in-flight call. The agent receives a structured error, not the tool response (which was never obtained or cannot be trusted). The audit chain records the fault. If the TEE recovers (e.g., the runtime process restarts and re-attests), subsequent calls in a new session may proceed.
**Behavior**:
1. In-flight call is abandoned. No tool response is forwarded to the agent.
2. A structured error is returned to the agent over the existing HTTP/SSE connection (if the connection is still alive). If the connection is also lost, the agent MCP client receives a connection error.
3. An audit chain entry is written for the failed call (see TRACE Claim structure below).
-4. The gateway process exits if the TEE fault is unrecoverable. The orchestrator restarts it; a new attestation report is obtained on restart.
+4. The runtime process exits if the TEE fault is unrecoverable. The orchestrator restarts it; a new attestation report is obtained on restart.
**Structured error returned to agent**:
```json
@@ -112,7 +112,7 @@ Closes #22.
"id": "call-42",
"error": {
"code": -32099,
- "message": "Gateway internal fault",
+ "message": "Runtime internal fault",
"data": {
"call_id": "call-42",
"fault_type": "tee_fault",
@@ -146,7 +146,7 @@ Closes #22.
"call_id": "call-42",
"session_id": "sess_01JABCDE",
"fault_detail": "Enclave watchdog timeout after 30000ms",
- "action": "call_abandoned_gateway_restarting"
+ "action": "call_abandoned_runtime_restarting"
}
```
@@ -154,14 +154,14 @@ Closes #22.
## FM-4: Policy Bundle Hash Mismatch at Startup
-**Trigger**: The gateway loads its Cedar policy bundle at startup and measures its hash. If the measured hash does not match the expected hash in the deployment manifest (set at deploy time, part of the TEE measurement or a separate signed manifest), the gateway refuses to start.
+**Trigger**: The runtime loads its Cedar policy bundle at startup and measures its hash. If the measured hash does not match the expected hash in the deployment manifest (set at deploy time, part of the TEE measurement or a separate signed manifest), the runtime refuses to start.
-**Decision**: Fail-closed. Gateway does not start. This prevents a swapped or tampered policy bundle from being used. A silently different policy would undermine the governance guarantee: the TRACE Claim asserts a specific policy bundle hash, and if that hash is wrong, every claim produced would be a lie.
+**Decision**: Fail-closed. Runtime does not start. This prevents a swapped or tampered policy bundle from being used. A silently different policy would undermine the governance guarantee: the TRACE Claim asserts a specific policy bundle hash, and if that hash is wrong, every claim produced would be a lie.
**Behavior**:
-1. At startup, before binding any port, the gateway reads the policy bundle from disk and computes its SHA-256 hash.
-2. The gateway compares the computed hash against the expected hash from the signed deployment manifest.
-3. If they do not match, the gateway writes a log entry and exits with a non-zero status code.
+1. At startup, before binding any port, the runtime reads the policy bundle from disk and computes its SHA-256 hash.
+2. The runtime compares the computed hash against the expected hash from the signed deployment manifest.
+3. If they do not match, the runtime writes a log entry and exits with a non-zero status code.
4. No TRACE Claims are produced.
**Log entry format**:
@@ -185,7 +185,7 @@ Closes #22.
## FM-5: MCP Protocol Parse Failure
-**Trigger**: The gateway receives a message from the agent MCP client that is malformed JSON-RPC, uses an unsupported JSON-RPC version, violates the MCP protocol schema, or is crafted to exploit a parser (e.g., deeply nested structures, oversized payloads, binary data in a text field).
+**Trigger**: The runtime receives a message from the agent MCP client that is malformed JSON-RPC, uses an unsupported JSON-RPC version, violates the MCP protocol schema, or is crafted to exploit a parser (e.g., deeply nested structures, oversized payloads, binary data in a text field).
**Decision**: Fail-closed on the specific call. The session continues; only the failing call is rejected. A structured parse error is returned to the agent. The raw payload hash (not the content) is logged for forensics. The full payload is not logged to avoid storing attacker-controlled data.
@@ -194,7 +194,7 @@ Closes #22.
2. Structured error is returned to the agent MCP client.
3. Log entry records the call_id (if parseable), session_id, error type, and a SHA-256 hash of the raw payload bytes.
4. The session remains open. Subsequent well-formed calls are processed normally.
-5. Rate limiting: if a session sends more than N parse failures within a configurable window, the gateway closes the session (configurable threshold, default: 10 failures in 60 seconds).
+5. Rate limiting: if a session sends more than N parse failures within a configurable window, the runtime closes the session (configurable threshold, default: 10 failures in 60 seconds).
**Structured error returned to agent**:
```json
diff --git a/docs/spec/phase2-server.md b/docs/spec/phase2-server.md
index 1d7a15b1..1f114d6e 100644
--- a/docs/spec/phase2-server.md
+++ b/docs/spec/phase2-server.md
@@ -1,4 +1,4 @@
-# Phase 2 cMCP Server Specification
+# Phase 2 cMCP Server Specification
---
Status: Draft v0.1
@@ -8,9 +8,9 @@ Stability: Unstable — expect breaking changes before v1.0
## Section 1 — Phase 2 Architecture Overview
-Phase 2 targets a different buyer than Phase 1. The Phase 1 buyer is an agent developer who deploys a gateway in front of their own agents. The Phase 2 buyer is a SaaS vendor or AI platform provider who exposes MCP endpoints to enterprise customers. Their enterprise customers — Phase 1 buyers — eventually ask: "prove your server code has not changed since I approved it." Phase 2 answers that question.
+Phase 2 targets a different buyer than Phase 1. The Phase 1 buyer is an agent developer who deploys a runtime in front of their own agents. The Phase 2 buyer is a SaaS vendor or AI platform provider who exposes MCP endpoints to enterprise customers. Their enterprise customers — Phase 1 buyers — eventually ask: "prove your server code has not changed since I approved it." Phase 2 answers that question.
-Phase 1 closes from the agent side: the gateway attests what the agent sent and what policy was applied. Phase 2 closes from the server side: the MCP server binary, its tool surface, and its egress behavior are all measured inside a TEE and published as a second TRACE Claim that any enterprise verifier can check without trusting the SaaS operator.
+Phase 1 closes from the agent side: the runtime attests what the agent sent and what policy was applied. Phase 2 closes from the server side: the MCP server binary, its tool surface, and its egress behavior are all measured inside a TEE and published as a second TRACE Claim that any enterprise verifier can check without trusting the SaaS operator.
Phase 2 also closes two Phase 1 residuals:
@@ -42,7 +42,7 @@ SaaS / Platform Provider
(DB / APIs / customer data)
```
-The combined trust artifact delivered to the verifier is a pair of TRACE Claims: the Phase 1 gateway claim (proves gateway policy ran) and the Phase 2 server claim (proves server binary and tool surface are attested). Neither claim requires trusting the other party's operator.
+The combined trust artifact delivered to the verifier is a pair of TRACE Claims: the Phase 1 runtime claim (proves runtime policy ran) and the Phase 2 server claim (proves server binary and tool surface are attested). Neither claim requires trusting the other party's operator.
**Sequencing note.** Phase 2 is the natural pull from Phase 1 adoption. It is not the current build focus. Revisit after Phase 1 GA and first design partner cohort feedback.
@@ -56,7 +56,7 @@ Each property below is something a TEE measurement can prove that a software-onl
**Definition.** The binary running right now is the binary attested — not just signed at some earlier moment.
-**What is measured.** At TEE startup, the container image digest of the MCP server binary is measured into the attestation report. This is the same mechanism Phase 1 uses for the gateway, now applied to the server.
+**What is measured.** At TEE startup, the container image digest of the MCP server binary is measured into the attestation report. This is the same mechanism Phase 1 uses for the runtime, now applied to the server.
**Attestation field.** `server_attestation.container_image_digest`
@@ -90,7 +90,7 @@ Each property below is something a TEE measurement can prove that a software-onl
**Verification.** The verifier checks the egress policy hash against the approved policy on record. An enterprise can verify that the MCP server cannot call an unapproved upstream service (for example, an external model API that was not in scope when the server was approved) because any deviation from the measured egress policy is detectable.
-**What this closes.** P1.4 transitive trust. Phase 1 attests that the gateway ran the approved policy against the agent's call. Phase 1 cannot attest what the server did next. Phase 2 closes this: the server's own upstream dependencies are part of the attested measurement, and a verifier can confirm the server's transitive call graph was bounded at startup.
+**What this closes.** P1.4 transitive trust. Phase 1 attests that the runtime ran the approved policy against the agent's call. Phase 1 cannot attest what the server did next. Phase 2 closes this: the server's own upstream dependencies are part of the attested measurement, and a verifier can confirm the server's transitive call graph was bounded at startup.
---
@@ -120,7 +120,7 @@ Software-only isolation (`shared_tee_sw_only`) must be labeled explicitly. Verif
**Definition.** Party A (an agent from enterprise A) can verify party B's (a SaaS vendor's) MCP server directly — without a shared operator in the chain and without trusting either party's infrastructure claims.
-**Implementation.** The Phase 1 gateway TRACE Claim includes a `server_trace_claim_ref` field pointing to the server's Phase 2 TRACE Claim. The agent (or its gateway) performs two independent verifications:
+**Implementation.** The Phase 1 runtime TRACE Claim includes a `server_trace_claim_ref` field pointing to the server's Phase 2 TRACE Claim. The agent (or its runtime) performs two independent verifications:
1. Phase 1 gateway TRACE Claim — proves the gateway's Cedar policy ran and was hardware-attested.
2. Phase 2 server TRACE Claim — proves the server binary and tool surface are attested.
@@ -131,7 +131,7 @@ Neither verification requires trusting the other party's operator. Both claims a
```json
{
- "phase1_gateway_claim": "",
+ "phase1_runtime_claim": "",
"phase2_server_claim_url": "https://attestation.vendor.com/claims/",
"phase2_server_claim": ""
}
@@ -149,9 +149,9 @@ The Phase 2 proxy adds payload inspection — content classification and per-fie
Three placement options:
-**Inline (synchronous).** The gateway buffers the entire response before classifying. Latency penalty: `response_size / classification_throughput`. Not viable for streaming — buffering defeats the purpose of streaming and introduces unbounded latency for large payloads.
+**Inline (synchronous).** The runtime buffers the entire response before classifying. Latency penalty: `response_size / classification_throughput`. Not viable for streaming — buffering defeats the purpose of streaming and introduces unbounded latency for large payloads.
-**Async (default).** The gateway begins streaming the response to the agent immediately. Classification runs concurrently on the streamed chunks. If classification detects a violation partway through:
+**Async (default).** The runtime begins streaming the response to the agent immediately. Classification runs concurrently on the streamed chunks. If classification detects a violation partway through:
1. Send a control message to the agent signaling that the in-progress response is being terminated.
2. Close the streaming connection to the agent.
@@ -207,7 +207,7 @@ These targets apply to the proxy classification path under nominal load with a r
### Phase 1 Stance
-Phase 1 is single-tenant by design. One gateway instance = one policy bundle = one audit chain = one customer or business unit. If multiple business units deploy the same gateway binary with different policy bundles, each instance is treated as a separate single-tenant deployment. Multi-tenancy is out of Phase 1 scope.
+Phase 1 is single-tenant by design. One runtime instance = one policy bundle = one audit chain = one customer or business unit. If multiple business units deploy the same runtime binary with different policy bundles, each instance is treated as a separate single-tenant deployment. Multi-tenancy is out of Phase 1 scope.
### Phase 2 Options for Multi-Tenant MCP Servers
diff --git a/docs/spec/response-inspection.md b/docs/spec/response-inspection.md
index 2caa937a..2cb739c8 100644
--- a/docs/spec/response-inspection.md
+++ b/docs/spec/response-inspection.md
@@ -1,10 +1,10 @@
-# Response Inspection
+# Response Inspection
Status: Draft v0.1 | Closes #37 | Related: [session-policy.md](session-policy.md) (state handoff), [call-graph.md](call-graph.md) (tagging)
## Overview
-Response inspection runs **after** the MCP tool call returns, before the gateway passes the response payload to the agent. This is a deliberate architectural choice: Cedar pre-call policy evaluates context that is known before the call (principal identity, tool catalog entry, session state, request arguments). It cannot inspect a response that does not yet exist. Post-call inspection therefore runs in gateway code, not in Cedar, and produces two outputs: (1) an allow/deny decision that gates whether the response reaches the agent, and (2) updated session state that gates future calls in the same session.
+Response inspection runs **after** the MCP tool call returns, before the runtime passes the response payload to the agent. This is a deliberate architectural choice: Cedar pre-call policy evaluates context that is known before the call (principal identity, tool catalog entry, session state, request arguments). It cannot inspect a response that does not yet exist. Post-call inspection therefore runs in runtime code, not in Cedar, and produces two outputs: (1) an allow/deny decision that gates whether the response reaches the agent, and (2) updated session state that gates future calls in the same session.
This separation is explicit. Cedar owns pre-call authorization. The inspection pipeline owns post-call classification and session state mutation. Session state then feeds back into Cedar on the next call.
@@ -14,7 +14,7 @@ The pipeline runs sequentially on every tool response before it is passed to the
### Stage 1: Size Check
-If `Content-Length` (or, where absent, the measured response size) exceeds `max_response_size_bytes` (default: 2 097 152 bytes / 2 MB, configurable per deployment), the response is denied immediately. The size limit exists to prevent memory exhaustion in the gateway and to bound the cost of downstream pattern matching.
+If `Content-Length` (or, where absent, the measured response size) exceeds `max_response_size_bytes` (default: 2 097 152 bytes / 2 MB, configurable per deployment), the response is denied immediately. The size limit exists to prevent memory exhaustion in the runtime and to bound the cost of downstream pattern matching.
Return shape on denial:
@@ -26,7 +26,7 @@ All remaining stages are still recorded as `"skip"` in the audit entry so the en
### Stage 2: Schema Validation
-If the tool has an approved `output_schema` in the catalog, the gateway validates the response JSON against it using JSON Schema draft-07.
+If the tool has an approved `output_schema` in the catalog, the runtime validates the response JSON against it using JSON Schema draft-07.
- **Surplus fields** — fields present in the response but absent from the approved schema — are collected as `surplus_fields`.
- **Missing required fields** — fields required by the schema but absent from the response — are a tool implementation error, not a policy violation. They are logged and the response passes through.
@@ -39,13 +39,13 @@ The handling mode for surplus fields comes from the catalog entry (overridable b
| `strict` | Deny the response if any surplus fields are present. |
| `log` | Pass through unchanged; record surplus fields in audit entry. |
-**Canonical JSON for surplus stripping (redact mode):** The gateway reconstructs the response by walking the approved schema and copying only the fields named there from the raw response. The result is re-serialized as compact JSON (no extra whitespace, keys in schema-definition order). This canonical form is what gets hashed for `response_payload_hash` in the audit entry. If the original response was not valid JSON (e.g., plain text or binary), the entire response is treated as a single opaque value; schema validation is skipped and the mode is recorded as `"skip_non_json"`.
+**Canonical JSON for surplus stripping (redact mode):** The runtime reconstructs the response by walking the approved schema and copying only the fields named there from the raw response. The result is re-serialized as compact JSON (no extra whitespace, keys in schema-definition order). This canonical form is what gets hashed for `response_payload_hash` in the audit entry. If the original response was not valid JSON (e.g., plain text or binary), the entire response is treated as a single opaque value; schema validation is skipped and the mode is recorded as `"skip_non_json"`.
If no approved `output_schema` exists in the catalog, this stage result is `"skip"`.
### Stage 3: Sensitivity Classification
-Cedar does not run post-call. Sensitivity classification in Phase 1 is rule-based in gateway code. Three sources are combined in priority order:
+Cedar does not run post-call. Sensitivity classification in Phase 1 is rule-based in runtime code. Three sources are combined in priority order:
1. **Catalog-level `sensitivity_level` annotation** — always applied. If the tool is annotated `"hipaa_phi"`, every response from it carries that tag regardless of content.
2. **Field-level annotations in `approved_definition.output_schema`** — fields tagged with sensitivity labels (e.g., `"ssn"` tagged `"pii"`, `"diagnosis"` tagged `"hipaa_phi"`) contribute their tags to the response if those fields are present and non-null in the response.
@@ -55,7 +55,7 @@ Output: a set of sensitivity tags applied to this response, for example `["pii",
### Stage 4: Indirect Injection Detection
-The gateway scans response content for patterns that resemble injected instructions the LLM would treat as system context. A match causes a denial. The pattern list is configurable per deployment — the set below is the Phase 1 default, maintained as a config file, not hardcoded.
+The runtime scans response content for patterns that resemble injected instructions the LLM would treat as system context. A match causes a denial. The pattern list is configurable per deployment — the set below is the Phase 1 default, maintained as a config file, not hardcoded.
```python
INJECTION_PATTERNS = [
diff --git a/docs/spec/session-policy.md b/docs/spec/session-policy.md
index eab3ab99..0011e638 100644
--- a/docs/spec/session-policy.md
+++ b/docs/spec/session-policy.md
@@ -1,4 +1,4 @@
-# Session Policy
+# Session Policy
Status: Draft v0.1 | Closes #36 | Related: [response-inspection.md](response-inspection.md) (feeds this), [call-graph.md](call-graph.md) (uses this)
@@ -129,17 +129,17 @@ In Policy 3, `sensitivity_level_int` is a derived integer attribute on the sessi
}
```
-**When reset is not possible or not yet called:** If the gateway is in enforcement mode and `max_sensitivity` is `"hipaa_phi"`, `"mnpi"`, or `"trade_secret"`, outbound calls to non-covered or non-approved destinations are denied by Cedar egress policy (see above). The agent cannot unblock itself. There is no agent-callable override endpoint.
+**When reset is not possible or not yet called:** If the runtime is in enforcement mode and `max_sensitivity` is `"hipaa_phi"`, `"mnpi"`, or `"trade_secret"`, outbound calls to non-covered or non-approved destinations are denied by Cedar egress policy (see above). The agent cannot unblock itself. There is no agent-callable override endpoint.
-This is intentional. The agent is an LLM: it is non-deterministic, and the gateway cannot trust agent assertions about what is or is not in its context window. Once a session has handled high-sensitivity data, the only entity that can attest "this session is now clean" is a human operator who has verified the agent's context. The reset endpoint is the mechanism for that attestation.
+This is intentional. The agent is an LLM: it is non-deterministic, and the runtime cannot trust agent assertions about what is or is not in its context window. Once a session has handled high-sensitivity data, the only entity that can attest "this session is now clean" is a human operator who has verified the agent's context. The reset endpoint is the mechanism for that attestation.
-If an operator reset is not available (e.g., the gateway is processing automated batch jobs with no operator in the loop), the correct architectural response is to provision short-lived sessions scoped to a single sensitivity domain, rather than relying on reset.
+If an operator reset is not available (e.g., the runtime is processing automated batch jobs with no operator in the loop), the correct architectural response is to provision short-lived sessions scoped to a single sensitivity domain, rather than relying on reset.
## Session Lifetime and Attestation Validity
A session's maximum duration is bounded by the attestation validity period of the agent's TRACE token. When the TRACE token expires, the session must end — the gateway cannot continue to enforce session-level policy for an agent whose identity and configuration are no longer attested.
-In practice: session `max_duration_seconds` is set to `min(configured_session_max, trace_token_ttl_remaining)` at session creation. A session that is still active when its TRACE token would expire is terminated by the gateway with an audit entry of type `"session_expired"`.
+In practice: session `max_duration_seconds` is set to `min(configured_session_max, trace_token_ttl_remaining)` at session creation. A session that is still active when its TRACE token would expire is terminated by the runtime with an audit entry of type `"session_expired"`.
This means a long-running agent that handles high-sensitivity data early in its session will face increasingly tight call restrictions as the session progresses — both because `max_sensitivity` is monotonically increasing and because the TRACE token TTL is monotonically decreasing. Deployments should size TRACE token lifetimes to match expected task durations.
diff --git a/docs/spec/threat-model.md b/docs/spec/threat-model.md
index b907e7ac..48b17a12 100644
--- a/docs/spec/threat-model.md
+++ b/docs/spec/threat-model.md
@@ -1,12 +1,12 @@
-# Threat Model
+# Threat Model
-Status: Draft v0.1 | Covers: Phase 1 cMCP Gateway
+Status: Draft v0.1 | Covers: Phase 1 cMCP Runtime
## Assets
| Asset | Sensitivity | Why it matters |
|-------|-------------|----------------|
-| Tool call payloads (PII, PHI, financial data in requests) | Critical | Core data the gateway is protecting |
+| Tool call payloads (PII, PHI, financial data in requests) | Critical | Core data the runtime is protecting |
| Tool responses (data returned to agent) | High | May contain more data than requested |
| Cedar policy bundle | Critical | Defines what is allowed; tampering enables bypass |
| Audit chain + signing key | Critical | Tampered audit chain can't be detected post-breach |
@@ -24,29 +24,29 @@ Status: Draft v0.1 | Covers: Phase 1 cMCP Gateway
**A2: Supply chain attacker**
- Has compromised a dependency, a build pipeline, or a package registry
-- Can insert malicious code into the gateway binary or its dependencies
+- Can insert malicious code into the runtime binary or its dependencies
- Cannot change the binary after TEE measurement without invalidating the attestation report
-- Goal: modify gateway behavior without detection
+- Goal: modify runtime behavior without detection
**A3: Malicious or compromised MCP server**
- Controls the tool's response payload
- Can craft responses designed to inject instructions or exfiltrate data
-- Cannot modify gateway policy or audit entries
+- Cannot modify runtime policy or audit entries
- Goal: indirect prompt injection, data exfiltration via crafted responses
**A4: External attacker (network)**
-- Can attempt to connect to the gateway or intercept traffic
-- Gateway uses mTLS; must have a valid SPIFFE SVID to connect
+- Can attempt to connect to the runtime or intercept traffic
+- Runtime uses mTLS; must have a valid SPIFFE SVID to connect
- Goal: bypass auth, replay attacks, MitM
**A5: Compromised agent**
- The agent (LLM) produces unexpected or adversarial tool calls
-- The gateway treats all agent tool calls as untrusted inputs
+- The runtime treats all agent tool calls as untrusted inputs
- Goal: call unauthorized tools, exfiltrate via authorized tools, exceed workflow scope
## STRIDE Analysis
-### cMCP Gateway (inside TEE)
+### cMCP Runtime (inside TEE)
| STRIDE | Threat | Mitigated by | Residual risk |
|--------|--------|-------------|---------------|
@@ -54,7 +54,7 @@ Status: Draft v0.1 | Covers: Phase 1 cMCP Gateway
| Tampering | A1 modifies Cedar policy on disk | Policy bundle hash measured at TEE startup; tampered bundle produces measurement mismatch | Runtime config injection (env vars, mounted secrets) not covered by measurement |
| Repudiation | A1 rewrites audit log after breach | Audit chain signing key is TEE-sealed; new valid signatures are computationally infeasible without the key | If the TEE is breached (physical attack, firmware vulnerability), key extraction is theoretically possible |
| Information Disclosure | A1 reads tool call payloads from host memory | SEV-SNP/TDX encrypts enclave memory; host hypervisor cannot read plaintext | Side-channel attacks (Spectre, cache timing) on the TEE boundary; TEE firmware vulnerabilities |
-| Denial of Service | A1 kills the gateway process | Standard process management; gateway has no availability SLA from the TEE itself | TEE cannot prevent the host from killing the process |
+| Denial of Service | A1 kills the runtime process | Standard process management; runtime has no availability SLA from the TEE itself | TEE cannot prevent the host from killing the process |
| Elevation of Privilege | A5 calls a tool not in the approved workflow | Per-workflow Cedar policy prevents out-of-workflow calls | Catalog must be correctly configured; a too-permissive catalog is operator error |
### MCP Protocol Interceptor
@@ -66,13 +66,13 @@ Status: Draft v0.1 | Covers: Phase 1 cMCP Gateway
| Repudiation | Tool server denies a call was made | Audit entry records call, tool server identity, and response hash | Tool server can deny it produced a specific response (only response hash is recorded, not content) |
| Information Disclosure | A3 returns more data than requested | Response schema validation strips surplus fields (redact mode) | Strict mode may be too disruptive; redact mode requires correct schema in catalog |
| Denial of Service | A3 returns oversized responses | Stage 1 size check (default 2MB limit) | DDoS via many simultaneous large responses |
-| Elevation of Privilege | A5 calls escalating sequence of individually-authorized tools crossing compliance boundary | Call graph tracking + session sensitivity policy | Gateway uses temporal adjacency, not true data provenance; sophisticated cross-system flows may not be detected |
+| Elevation of Privilege | A5 calls escalating sequence of individually-authorized tools crossing compliance boundary | Call graph tracking + session sensitivity policy | Runtime uses temporal adjacency, not true data provenance; sophisticated cross-system flows may not be detected |
### Tool Catalog
| STRIDE | Threat | Mitigated by | Residual risk |
|--------|--------|-------------|---------------|
-| Spoofing | A3 serves different tool definition than registered (rug-pull) | Tool catalog hash pinned in TEE attestation; drift detected via delta check | If the rug-pull happens before the gateway starts, it is measured into the catalog hash as correct |
+| Spoofing | A3 serves different tool definition than registered (rug-pull) | Tool catalog hash pinned in TEE attestation; drift detected via delta check | If the rug-pull happens before the runtime starts, it is measured into the catalog hash as correct |
| Tampering | A1 modifies catalog file on disk | Catalog hash measured at enclave startup; tampered catalog produces mismatch | Same as Cedar policy tampering |
| Repudiation | Unauthorized server added to catalog | Policy provenance manifest records who approved each catalog entry | Approver's identity is only as trustworthy as the identity system backing it |
| Information Disclosure | Catalog exposes sensitive server details | Catalog is inside the TEE; not externally accessible | N/A |
@@ -91,7 +91,7 @@ Verifiers must confirm that the egress policy hash excludes APM and telemetry en
### Server Swap / Tool Identity — T.1 (status: requires agent-side verification)
-The SPEC states T.1 is closed by the gateway producing an attestation report. T.1 is only closed if the agent (or the agent's gateway) verifies the attestation report before sending traffic. Without verification, the attestation exists as post-hoc evidence but provides no runtime protection against server swap at the moment of the call.
+The SPEC states T.1 is closed by the runtime producing an attestation report. T.1 is only closed if the agent (or the agent's runtime) verifies the attestation report before sending traffic. Without verification, the attestation exists as post-hoc evidence but provides no runtime protection against server swap at the moment of the call.
The verification library (`cmcp-verify`, see [verification-library.md](verification-library.md)) is required to close this threat. Deployments that do not run `cmcp-verify` (or an equivalent) treat attestation as audit evidence only, not as a runtime gate.
@@ -99,14 +99,14 @@ The verification library (`cmcp-verify`, see [verification-library.md](verificat
Hardware measurement at launch time proves the binary is what it should be. Runtime configuration injection — environment variables, mounted secrets, configuration files loaded after startup — happens after the measurement. A supply chain attack that operates via runtime configuration changes server behavior without changing the binary measurement.
-The binary-level protection is real and valuable. The runtime config gap must be stated explicitly in any compliance claim referencing this control. This is reflected in the Tampering row for the Gateway STRIDE table above (residual risk: runtime config injection not covered by measurement).
+The binary-level protection is real and valuable. The runtime config gap must be stated explicitly in any compliance claim referencing this control. This is reflected in the Tampering row for the Runtime STRIDE table above (residual risk: runtime config injection not covered by measurement).
## Compensating Controls (operator responsibilities)
These threats are real but outside the TEE's scope. Operators must address them separately:
-1. TEE firmware and microcode must be kept up to date (addresses Spectre-class side channels and the Information Disclosure residual risk in the Gateway table)
-2. SPIRE infrastructure must be secured (compromise enables SVID forgery, which negates the Spoofing mitigation for the gateway)
-3. Catalog approval process must be documented and audited (catalog entries are human-approved; the gateway trusts the catalog)
+1. TEE firmware and microcode must be kept up to date (addresses Spectre-class side channels and the Information Disclosure residual risk in the Runtime table)
+2. SPIRE infrastructure must be secured (compromise enables SVID forgery, which negates the Spoofing mitigation for the runtime)
+3. Catalog approval process must be documented and audited (catalog entries are human-approved; the runtime trusts the catalog)
4. Pattern list for injection detection must be maintained and updated (pattern-based detection in the MCP Protocol Interceptor has a residual false-negative risk)
5. Egress policy must explicitly exclude APM and telemetry endpoints to make the payload capture protection structural rather than operator-dependent
diff --git a/docs/spec/tool-identity.md b/docs/spec/tool-identity.md
index 45a9f9d1..f50e6146 100644
--- a/docs/spec/tool-identity.md
+++ b/docs/spec/tool-identity.md
@@ -1,4 +1,4 @@
-# Tool Identity and Catalog Specification
+# Tool Identity and Catalog Specification
---
Status: Draft v0.1
@@ -6,7 +6,7 @@ Last updated: 2026-06-04
Stability: Unstable — expect breaking changes before v1.0
---
-This document specifies how the cMCP Gateway identifies upstream MCP servers, prevents tool name collisions, and routes tool calls. These mechanisms close the protocol-level gap in MCP (issue #40): MCP defines no signed manifest binding a tool name to a publisher. The gateway closes this by maintaining a catalog that binds each tool name to a specific upstream server identity.
+This document specifies how the cMCP Runtime identifies upstream MCP servers, prevents tool name collisions, and routes tool calls. These mechanisms close the protocol-level gap in MCP (issue #40): MCP defines no signed manifest binding a tool name to a publisher. The runtime closes this by maintaining a catalog that binds each tool name to a specific upstream server identity.
---
@@ -34,11 +34,11 @@ spiffe:////
Example: `spiffe://corp.example/salesforce/mcp-server`
-SPIFFE SVIDs are issued by a SPIRE server shared between the gateway and the upstream servers. The gateway verifies the SVID against the SPIRE trust bundle at connection time. SPIFFE is the preferred identity anchor when the deployment includes a SPIRE server.
+SPIFFE SVIDs are issued by a SPIRE server shared between the runtime and the upstream servers. The runtime verifies the SVID against the SPIRE trust bundle at connection time. SPIFFE is the preferred identity anchor when the deployment includes a SPIRE server.
### Phase 1 Requirement
-In Phase 1, each catalog entry must include at least one identity anchor (`tls_fingerprint` or `spiffe_id`). Including both is preferred: the gateway verifies whichever anchors are present, and a mismatch on either is treated as an identity failure.
+In Phase 1, each catalog entry must include at least one identity anchor (`tls_fingerprint` or `spiffe_id`). Including both is preferred: the runtime verifies whichever anchors are present, and a mismatch on either is treated as an identity failure.
---
@@ -80,7 +80,7 @@ Each tool in the catalog has a full entry binding the tool name to its upstream
|-------|------|----------|-------------|
| `tool_name` | string | yes | Unique tool name as it appears in MCP. Must be unique across the entire catalog. |
| `server.display_name` | string | yes | Human-readable name for the upstream server. |
-| `server.url` | string | yes | URL the gateway routes calls to for this tool. |
+| `server.url` | string | yes | URL the runtime routes calls to for this tool. |
| `server.tls_fingerprint` | string | at least one of `tls_fingerprint` or `spiffe_id` | SHA-256 fingerprint of the server's TLS public key. |
| `server.spiffe_id` | string | at least one of `tls_fingerprint` or `spiffe_id` | SPIFFE SVID URI for the server. |
| `server.rotation_mode` | string | no (default: `key-pinned`) | `key-pinned` or `cert-pinned`. Controls how cert renewal is handled. See [Cert Rotation Policy](#cert-rotation-policy). |
@@ -91,7 +91,7 @@ Each tool in the catalog has a full entry binding the tool name to its upstream
### Definition Hash and Mutation Detection
-The `definition_hash` is computed at catalog approval time and included in the `tool_catalog.hash` measurement in the TRACE Claim. At runtime, the gateway fetches the live tool definition from the upstream server and compares it against `approved_definition`. If the live definition does not match:
+The `definition_hash` is computed at catalog approval time and included in the `tool_catalog.hash` measurement in the TRACE Claim. At runtime, the process fetches the live tool definition from the upstream server and compares it against `approved_definition`. If the live definition does not match:
- The call is denied.
- The audit log records the event as `definition_mismatch`.
@@ -105,7 +105,7 @@ This closes the rug-pull attack vector (P4.2): a compromised upstream server can
Tool name uniqueness is enforced at catalog load time (enclave startup).
-**Rule**: each `tool_name` must map to exactly one upstream server. If two catalog entries share the same `tool_name`, the gateway refuses to start.
+**Rule**: each `tool_name` must map to exactly one upstream server. If two catalog entries share the same `tool_name`, the runtime refuses to start.
**Error message**:
@@ -116,7 +116,7 @@ Duplicate tool name in catalog: "salesforce.query" is registered by two differen
Each tool name must map to exactly one upstream server.
```
-The gateway does not attempt to resolve the collision. It fails closed: no tools are available until the collision is resolved.
+The runtime does not attempt to resolve the collision. It fails closed: no tools are available until the collision is resolved.
**Resolution**: namespace the tool names. Example:
@@ -135,7 +135,7 @@ Silent collision resolution (e.g., last-write-wins or first-registered-wins) wou
## Section 4 -- Routing
-When the gateway receives a tool call for `tool_name`:
+When the runtime receives a tool call for `tool_name`:
1. Look up `tool_name` in the catalog.
- If not found: deny the call, log as `tool_not_in_catalog`.
@@ -154,7 +154,7 @@ When the gateway receives a tool call for `tool_name`:
6. Forward the tool call to the upstream server.
-7. Return the response to the gateway's response inspection pipeline.
+7. Return the response to the runtime's response inspection pipeline.
### Identity Mismatch Handling
@@ -165,7 +165,7 @@ An `identity_mismatch` event indicates one of:
- A man-in-the-middle or DNS hijack is in progress.
- The server was replaced with a different instance (legitimate infrastructure change, requires catalog update).
-In all cases, the gateway denies the call and does not forward any data to the server until the catalog is updated and the enclave is restarted with the new measurement.
+In all cases, the runtime denies the call and does not forward any data to the server until the catalog is updated and the enclave is restarted with the new measurement.
---
diff --git a/docs/spec/transport.md b/docs/spec/transport.md
index 4fb2f73d..e7c30504 100644
--- a/docs/spec/transport.md
+++ b/docs/spec/transport.md
@@ -16,9 +16,9 @@ Closes #20, #21.
| Transport | Phase 1 Status | Reason |
|-----------|---------------|--------|
-| HTTP/SSE | **In scope** | MCP server runs as a network-addressable process. The gateway terminates the connection at the TEE boundary, inspects each call, and forwards to the upstream server over a separate internal connection. No subprocess spawning required. |
+| HTTP/SSE | **In scope** | MCP server runs as a network-addressable process. The runtime terminates the connection at the TEE boundary, inspects each call, and forwards to the upstream server over a separate internal connection. No subprocess spawning required. |
| stdio | **Out of Phase 1 scope** | The stdio transport requires the agent (or MCP client) to spawn the MCP server as a child subprocess. A subprocess cannot cross the TEE boundary: the agent process lives outside the enclave and cannot fork a child that executes inside isolated TEE memory. The memory isolation guarantee of SEV-SNP, TDX, and TPM Trusted Launch is per-VM or per-enclave, not per-process-tree. Bridging stdio into the TEE would require a new component (see options below), deferred to Phase 2 or a future extension. |
-| WebSocket | **TBD** | WebSocket provides bidirectional framing over HTTP/1.1 or HTTP/2. The gateway can terminate WebSocket connections in principle; evaluation is deferred pending the MCP specification WebSocket profile stabilizing. |
+| WebSocket | **TBD** | WebSocket provides bidirectional framing over HTTP/1.1 or HTTP/2. The runtime can terminate WebSocket connections in principle; evaluation is deferred pending the MCP specification WebSocket profile stabilizing. |
---
@@ -32,7 +32,7 @@ Agent process
└── communicates over stdin/stdout (JSON-RPC 2.0 framing)
```
-For the gateway to intercept this traffic, it would need to run inside the same process tree as the agent, which contradicts TEE isolation. TEE isolation works at the VM boundary (SEV-SNP, TDX) or at the TPM-measured boot boundary. A process inside the TEE cannot be a child of a process outside the TEE. Allowing it would defeat the hardware attestation guarantee: the enclave measurement would no longer cover the full execution context.
+For the runtime to intercept this traffic, it would need to run inside the same process tree as the agent, which contradicts TEE isolation. TEE isolation works at the VM boundary (SEV-SNP, TDX) or at the TPM-measured boot boundary. A process inside the TEE cannot be a child of a process outside the TEE. Allowing it would defeat the hardware attestation guarantee: the enclave measurement would no longer cover the full execution context.
---
@@ -40,7 +40,7 @@ For the gateway to intercept this traffic, it would need to run inside the same
### Option A: stdio-to-HTTP Bridge (new component at TEE boundary)
-A new sidecar component runs outside the TEE and translates stdio JSON-RPC to HTTP/SSE. The gateway (inside the TEE) connects to the sidecar over localhost HTTP.
+A new sidecar component runs outside the TEE and translates stdio JSON-RPC to HTTP/SSE. The runtime (inside the TEE) connects to the sidecar over localhost HTTP.
```
Agent
@@ -53,14 +53,14 @@ Agent
| Dimension | Assessment |
|-----------|-----------|
| Agent changes required | Minimal: configure MCP client to use stdio-bridge binary instead of MCP server binary directly |
-| Attack surface | Increased. The stdio-bridge runs outside the TEE and can be tampered with. An attacker who compromises the bridge can inject or suppress tool calls before they reach the gateway. |
-| Attestation coverage | The bridge is not inside the TEE. Its behavior is not covered by the hardware attestation report. TRACE Claims reflect gateway decisions, not bridge fidelity. |
+| Attack surface | Increased. The stdio-bridge runs outside the TEE and can be tampered with. An attacker who compromises the bridge can inject or suppress tool calls before they reach the runtime. |
+| Attestation coverage | The bridge is not inside the TEE. Its behavior is not covered by the hardware attestation report. TRACE Claims reflect runtime decisions, not bridge fidelity. |
| Complexity | New component to build, deploy, and maintain. |
| Recommended for Phase 1 | No. The untrusted bridge segment weakens the security model. |
### Option B: Agent-side stdio Proxy (agent wraps stdio server, exposes HTTP/SSE)
-The agent developer wraps the stdio MCP server in a thin HTTP adapter that speaks HTTP/SSE externally. The gateway connects to the adapter endpoint as if it were a native HTTP/SSE MCP server.
+The agent developer wraps the stdio MCP server in a thin HTTP adapter that speaks HTTP/SSE externally. The runtime connects to the adapter endpoint as if it were a native HTTP/SSE MCP server.
```
Agent
@@ -99,33 +99,33 @@ The "zero code changes" claim applies only to the following configuration:
- The MCP server is containerized (Docker or OCI image).
- The MCP server already supports HTTP/SSE transport (not stdio-only).
- The MCP server does not depend on host-level resources: local filesystem mounts, host network interfaces, or host-specific library versions (e.g., a specific glibc ABI not present in the TEE base image).
-- The agent MCP client is configured to point to the gateway endpoint rather than the MCP server directly.
+- The agent MCP client is configured to point to the runtime endpoint rather than the MCP server directly.
-If any of these conditions are not met, code or configuration changes are required before the gateway can be used.
+If any of these conditions are not met, code or configuration changes are required before the runtime can be used.
---
## Concrete Agent-Side Configuration
-The gateway is the sole MCP endpoint the agent host is configured to reach. All MCP servers are registered with the gateway, not with the agent directly.
+The runtime is the sole MCP endpoint the agent host is configured to reach. All MCP servers are registered with the runtime, not with the agent directly.
### YAML example
```yaml
# agent-config.yaml
mcp:
- # The agent host connects only to the cMCP Gateway.
+ # The agent host connects only to the cMCP Runtime.
# No direct connections to individual MCP servers.
- gateway_endpoint: "https://cmcp-gateway.internal:4433"
+ gateway_endpoint: "https://cmcp-runtime.internal:4433"
tls:
- ca_cert: "/etc/cmcp/gateway-ca.pem"
+ ca_cert: "/etc/cmcp/runtime-ca.pem"
# SPIFFE SVID for mutual TLS (issued only after TEE attestation succeeds)
client_cert: "/var/run/spire/svids/agent.pem"
client_key: "/var/run/spire/svids/agent.key"
# The agent does not list individual MCP servers here.
- # The gateway tool catalog is the authoritative list of available tools.
- # servers: [] # empty -- gateway handles routing
+ # The runtime tool catalog is the authoritative list of available tools.
+ # servers: [] # empty -- runtime handles routing
```
### JSON example (alternative)
@@ -133,9 +133,9 @@ mcp:
```json
{
"mcp": {
- "gateway_endpoint": "https://cmcp-gateway.internal:4433",
+ "gateway_endpoint": "https://cmcp-runtime.internal:4433",
"tls": {
- "ca_cert": "/etc/cmcp/gateway-ca.pem",
+ "ca_cert": "/etc/cmcp/runtime-ca.pem",
"client_cert": "/var/run/spire/svids/agent.pem",
"client_key": "/var/run/spire/svids/agent.key"
}
@@ -143,7 +143,7 @@ mcp:
}
```
-The agent host must not have direct network routes to any MCP server. Network policy (Kubernetes NetworkPolicy, security group, or firewall rule) enforces this. The gateway is the only reachable MCP endpoint from the agent network namespace.
+The agent host must not have direct network routes to any MCP server. Network policy (Kubernetes NetworkPolicy, security group, or firewall rule) enforces this. The runtime is the only reachable MCP endpoint from the agent network namespace.
---
@@ -151,7 +151,7 @@ The agent host must not have direct network routes to any MCP server. Network po
### Problem Statement
-SPIFFE SVID issuance must be conditioned on successful TEE attestation. If a SVID can be issued without attestation, any process -- attested or not -- can claim a gateway identity. The binding is the critical-path item for Phase 1: without it, the chain of trust has a gap between hardware measurement and workload identity.
+SPIFFE SVID issuance must be conditioned on successful TEE attestation. If a SVID can be issued without attestation, any process -- attested or not -- can claim a runtime identity. The binding is the critical-path item for Phase 1: without it, the chain of trust has a gap between hardware measurement and workload identity.
### Standards Basis
@@ -184,8 +184,8 @@ TEE boots
**Goal**: Confirm that a SPIFFE SVID can be issued if and only if TEE attestation succeeds, using at least one provider (TPM recommended for accessibility).
**Pass conditions**:
-1. SPIRE issues an SVID to the gateway workload only after the TEE attestation plugin returns a successful result.
-2. If the TPM PCR values are tampered with (e.g., by modifying the boot sequence in a test VM), SPIRE refuses to issue the SVID and the gateway does not start.
+1. SPIRE issues an SVID to the runtime workload only after the TEE attestation plugin returns a successful result.
+2. If the TPM PCR values are tampered with (e.g., by modifying the boot sequence in a test VM), SPIRE refuses to issue the SVID and the runtime does not start.
3. The SVID contains a SPIFFE ID that encodes the TEE provider and measurement (or a reference to it).
**Fail conditions**:
diff --git a/docs/spec/verification-library.md b/docs/spec/verification-library.md
index 2072ed16..bd96de3d 100644
--- a/docs/spec/verification-library.md
+++ b/docs/spec/verification-library.md
@@ -1,4 +1,4 @@
-# cmcp-verify: Verification Library Interface Spec
+# cmcp-verify: Verification Library Interface Spec
---
Status: Draft v0.1
@@ -71,7 +71,7 @@ def verify_trace_claim(
2. Verify the EK certificate chains to a trusted manufacturer CA (TPM manufacturer CA roots are published by Microsoft, Amazon, Google for their vTPM implementations).
3. Extract the TPM2B_ATTEST structure from attestation_report.raw_evidence.
4. Verify the TPM2_Quote signature using the Attestation Key (AK) public key, which must be certified by the EK.
-5. Confirm the quote's qualifying_data matches SHA-256(tee_public_key || session_id) from the TRACE Claim -- this binds the quote to the specific gateway instance.
+5. Confirm the quote's qualifying_data matches SHA-256(tee_public_key || session_id) from the TRACE Claim -- this binds the quote to the specific runtime instance.
6. Confirm the PCR values in the quote match attestation_report.measurement (compare byte-by-byte).
7. If all checks pass: TEE identity is verified for TPM.
@@ -146,4 +146,4 @@ if not result.is_attestation_fresh:
## Relationship to Threat Model
-As noted in [threat-model.md](threat-model.md), T.1 (server swap / tool identity) is only closed if the agent or the agent's gateway runs `verify_trace_claim` before sending traffic. Attestation without verification is post-hoc evidence, not a runtime gate.
+As noted in [threat-model.md](threat-model.md), T.1 (server swap / tool identity) is only closed if the agent or the agent's runtime runs `verify_trace_claim` before sending traffic. Attestation without verification is post-hoc evidence, not a runtime gate.
diff --git a/docs/testing/benchmarks.md b/docs/testing/benchmarks.md
index 6557481c..7a0de2b0 100644
--- a/docs/testing/benchmarks.md
+++ b/docs/testing/benchmarks.md
@@ -1,19 +1,19 @@
-# cMCP Gateway — Latency Targets and Benchmark Specification
+# cMCP Runtime — Latency Targets and Benchmark Specification
Closes #27.
## Overview
-This document defines latency targets and the benchmark methodology for the cMCP Gateway. Targets are split by phase:
+This document defines latency targets and the benchmark methodology for the cMCP Runtime. Targets are split by phase:
-- **Phase 1**: Gateway intercept path only (Cedar policy evaluation, audit entry creation, routing). No payload inspection.
+- **Phase 1**: Runtime intercept path only (Cedar policy evaluation, audit entry creation, routing). No payload inspection.
- **Phase 2**: Full proxy path with payload inspection (pattern-based and model-based classification).
---
## Phase 1 Targets
-### Attestation Handshake (one-time, at gateway startup)
+### Attestation Handshake (one-time, at runtime startup)
Attestation is a startup cost, not a per-call cost. It is not included in the per-call latency budget.
@@ -24,7 +24,7 @@ Attestation is a startup cost, not a per-call cost. It is not included in the pe
| TDX | < 100ms | Azure DCedsv5, GCP C3 |
| Opaque Managed | < 50ms | Opaque Managed Runtime, highest assurance |
-### Per-Call Gateway Overhead
+### Per-Call Runtime Overhead
Covers Cedar policy evaluation + audit entry creation + routing. Excludes upstream tool execution time.
@@ -46,7 +46,7 @@ Expected breakdown for a 10-rule policy bundle:
## Phase 2 Targets
-Phase 2 adds payload inspection between gateway receive and upstream forward.
+Phase 2 adds payload inspection between runtime receive and upstream forward.
| Path | p50 | p95 | p99 |
|------------------------------------------------|---------|---------|---------|
@@ -107,7 +107,7 @@ Collect the following per run, in microseconds unless noted:
|---------------------------|-------|-------------------------------------------------------------------------------|
| `cedar_eval_latency_us` | µs | Cedar policy evaluation time |
| `audit_entry_latency_us` | µs | Time to hash and append audit chain entry |
-| `routing_latency_us` | µs | Time from gateway receive to first byte sent to upstream |
+| `routing_latency_us` | µs | Time from runtime receive to first byte sent to upstream |
| `end_to_end_latency_us` | µs | Time from agent request received to response returned (excludes upstream) |
| `attestation_handshake_ms`| ms | Measured once at startup, not per-call |
diff --git a/docs/testing/soak-test.md b/docs/testing/soak-test.md
index 5e1864df..4dcc7ca3 100644
--- a/docs/testing/soak-test.md
+++ b/docs/testing/soak-test.md
@@ -1,4 +1,4 @@
-# cMCP Gateway — 72-Hour Soak Test Plan
+# cMCP Runtime — 72-Hour Soak Test Plan
Closes #31.
@@ -20,7 +20,7 @@ Surface stability failures that only emerge under sustained load and time. Short
|---------------------|-----------------------------------------------------------------------|
| Duration | 72 hours continuous |
| Load pattern | Alternating blocks: 1 hour active (100 calls/hour), 1 hour idle (0 calls). Repeat 36 times. |
-| HTTP proxy | nginx as reverse proxy between test client and gateway (simulates corporate firewall) |
+| HTTP proxy | nginx as reverse proxy between test client and runtime (simulates corporate firewall) |
| TEE providers | TPM (mandatory); one of SEV-SNP or TDX (mandatory if available in CI) |
| Cedar policy | 10-rule allowlist, enforcing mode |
| Session type | Long-running: session_id persists for 4 hours, then a new session starts |
@@ -45,7 +45,7 @@ Each edge case must be explicitly tested and logged. A soak run does not pass if
**Setup:** Set `attestation_validity_seconds = 14400` (4 hours). Sessions are 4 hours long, so expiration coincides with session boundary.
-**What to check:** When attestation expires, the gateway must either:
+**What to check:** When attestation expires, the runtime must either:
- Re-attest without service interruption, or
- Terminate the session with a clean error and issue a new attestation for the next session.
@@ -87,7 +87,7 @@ Absolute threshold: enclave memory at T=72h must be less than:
**Setup:** During the 1-hour idle periods, confirm that MCP connections are properly handled. Cloud networking rules may close idle TCP connections after 10 minutes.
**What to check:**
-- Does the gateway maintain idle upstream connections?
+- Does the runtime maintain idle upstream connections?
- Does it detect and re-establish connections after a cloud NAT timeout?
**Success:** After a 1-hour idle period, the first active-period call succeeds within 2x normal p99 latency (to account for connection re-establishment).
@@ -110,7 +110,7 @@ Absolute threshold: enclave memory at T=72h must be less than:
All items must pass for the soak run to be marked successful.
-- [ ] 0 gateway crashes over 72 hours
+- [ ] 0 runtime crashes over 72 hours
- [ ] 0 TRACE Claims with attestation gaps (every call in the active period appears in the audit chain)
- [ ] Memory growth bounded (within the threshold defined above)
- [ ] All 10 SSE streaming calls complete without silent disconnection