Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Removed

- The `opaque` attestation provider and its verifier. `cmcp_runtime.tee.opaque`
was a placeholder that only raised, and `cmcp_verify.opaque` marked
`hardware_attestation` verified on an unsigned `verified: true` from a remote
endpoint, which is not evidence. Gone with them: `TEEProvider.OPAQUE`, the
`ATTESTATION_PROVIDER_NOT_IMPLEMENTED` error, the `opaque` and
`opaque-managed` platform branches in `verify_trace_claim`, and the
`CMCP_OPAQUE_ATTESTATION_ENDPOINT` and `OPAQUE_API_KEY` variables. A config
naming `attestation.provider: opaque` now fails with the same `ConfigError`
as any unknown provider. The spec no longer lists a `highest` value for
`attestation_assurance`, which only that provider used.

### Changed

- Test fixtures and docs use vendor-neutral example model names.
- LICENSE and NOTICE name the copyright holder as AgenTrust Contributors. The
previous LICENSE line credited Agentic AI Foundation contributors, but the
foundation has not accepted the project. CHARTER.md and GOVERNANCE.md now say
Expand Down
3 changes: 1 addition & 2 deletions LIMITATIONS.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ Three things follow, and all three are gaps rather than theoretical concerns.

What cMCP does carry across calls is `session_max_sensitivity`, a monotonic ratchet that a caller cannot lower. Where the sensitive read *does* go through the gateway, a policy denying external-destination calls above a sensitivity floor will stop the egress leg, and that is a real defence rather than a hypothetical one. It depends on the operator having written that policy, and it does not apply when the read bypasses the gateway, which is the common case for a coding assistant.

Two things this entry deliberately does not claim. The study's compliance figures are an average over eleven models under one costume and one channel split, moving from 42% to 82%; several models complied with the blunt single-instruction version too, so "models refuse until you split it" is not accurate as a general statement. And while Claude Sonnet 4.6 and Opus 4.6 held at 0% across every split in the tabulated configuration, the same write-up reports a separate run in which Sonnet called the tool and redacted the obvious secrets while still returning proprietary source with a live key inside it. Model choice is not a control.
Two things this entry deliberately does not claim. The study's compliance figures are an average over eleven models under one costume and one channel split, moving from 42% to 82%; several models complied with the blunt single-instruction version too, so "models refuse until you split it" is not accurate as a general statement. And while two of the models held at 0% across every split in the tabulated configuration, the same write-up reports a separate run in which one of them called the tool and redacted the obvious secrets while still returning proprietary source with a live key inside it. Model choice is not a control.

**APM and telemetry payload capture**
The TEE prevents plaintext from leaving the enclave to any destination not covered by the egress policy. This protection is structural only when the egress policy explicitly denies APM and telemetry endpoints. If the operator allowlists those endpoints in the Cedar policy, the TEE boundary does not prevent payload capture by the APM agent. A TRACE Claim with an egress policy that permits APM or SDK telemetry endpoints does not provide this protection. Verifiers must inspect the policy bundle hash and confirm the policy excludes those endpoints.
Expand Down Expand Up @@ -250,7 +250,6 @@ Attestation is a startup cost, not a per-call cost. Per-call gateway overhead co
| TPM | less than 500ms (hardware I/O bound) |
| SEV-SNP | less than 100ms (Azure DCasv5, AWS C6a Nitro) |
| TDX | less than 100ms (Azure DCedsv5, GCP C3) |
| OPAQUE Managed | less than 50ms |
| software-only | negligible |

### Per-call gateway overhead
Expand Down
13 changes: 4 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,9 +131,8 @@ Agent -> cMCP Runtime -> 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` _(opt-in)_ | OPAQUE Confidential Runtime | n/a _(not yet implemented)_ | Placeholder: excluded from auto-detect; selecting it explicitly raises a not-implemented error |

Provider auto-detect probe order: `azure-cvm -> tpm -> sev-snp -> tdx`. The first provider whose `detect()` succeeds is selected. `opaque` is a not-yet-implemented placeholder: it is excluded from auto-detect, and selecting it explicitly raises `ATTESTATION_PROVIDER_NOT_IMPLEMENTED` rather than falling through silently. If no hardware provider is detected, the gateway starts only under `CMCP_DEV_MODE=1` (a non-attested software-only fallback) and otherwise refuses to start.
Provider auto-detect probe order: `azure-cvm -> tpm -> sev-snp -> tdx`. The first provider whose `detect()` succeeds is selected. If no hardware provider is detected, the gateway starts only under `CMCP_DEV_MODE=1` (a non-attested software-only fallback) and otherwise refuses to start.

```python
from cmcp_runtime.config import TEEProvider
Expand All @@ -144,9 +143,6 @@ from cmcp_runtime.config import TEEProvider

# Explicit hardware selection
# attestation.provider: sev-snp

# OPAQUE Managed Runtime (opt-in only; not yet implemented)
# OPAQUE_ATTESTATION_URL=https://... cmcp start --config cmcp-config.yaml
```

---
Expand All @@ -169,7 +165,7 @@ Default is `enforcing`. Set `enforcement_mode: advisory` in `cmcp-config.yaml` t

```yaml
attestation:
provider: auto # auto | tpm | sev-snp | tdx | opaque | software-only
provider: auto # auto | tpm | sev-snp | tdx | software-only
enforcement_mode: enforcing # enforcing | advisory | silent
validity_seconds: 86400 # attestation freshness window (default: 24 hours)
staleness_policy: fail_closed # fail_closed | warn_only
Expand All @@ -189,7 +185,6 @@ Environment variables:
|---|---|
| `CMCP_DEV_MODE=1` | Use software-only TEE provider; no hardware required |
| `CMCP_BEARER_TOKEN` | Require this bearer token on all inbound requests |
| `OPAQUE_ATTESTATION_URL` | Enable OPAQUE Managed Runtime attestation (explicit opt-in) |

---

Expand Down Expand Up @@ -279,15 +274,15 @@ Software-only governance runs the policy engine in the same OS an operator or a

### Do I need special hardware to try it?

No. Set `CMCP_DEV_MODE=1` to use the software-only TEE provider and run the full quickstart without a hardware TEE. Hardware providers (TPM, AMD SEV-SNP, Intel TDX, OPAQUE) are used in production.
No. Set `CMCP_DEV_MODE=1` to use the software-only TEE provider and run the full quickstart without a hardware TEE. Hardware providers (TPM, AMD SEV-SNP, Intel TDX) are used in production.

### What is a TRACE Claim?

A TRACE Claim (a `GatewayClaim`) is a signed, hardware-attested artifact produced per session. It records which tools ran, which policy decided each call, the Cedar bundle hash, and the audit chain, and it is signed with an Ed25519 key that never leaves the TEE. A verifier checks it with the `cmcp_verify` library without trusting the operator.

### Which TEE providers are supported?

TPM 2.0 / vTPM, AMD SEV-SNP, and Intel TDX, with NVIDIA GPU confidential computing planned for v0.2 and OPAQUE Confidential Runtime available as explicit opt-in. Auto-detection order is Azure confidential VM, then TPM 2.0 / vTPM, then AMD SEV-SNP, then Intel TDX; the software-only provider is used only under CMCP_DEV_MODE=1.
TPM 2.0 / vTPM, AMD SEV-SNP, and Intel TDX, with NVIDIA GPU confidential computing planned for v0.2. Auto-detection order is Azure confidential VM, then TPM 2.0 / vTPM, then AMD SEV-SNP, then Intel TDX; the software-only provider is used only under CMCP_DEV_MODE=1.

### What license is cMCP under?

Expand Down
2 changes: 1 addition & 1 deletion SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ Timeline starts when the issue is confirmed as a valid vulnerability, not on ini

The following components are in scope:

- **TEE attestation path**: measurement of policy bundle hash into hardware attestation report; attestation verification logic for TPM 2.0, AMD SEV-SNP, Intel TDX, and OPAQUE Managed Runtime providers
- **TEE attestation path**: measurement of policy bundle hash into hardware attestation report; attestation verification logic for TPM 2.0, AMD SEV-SNP, and Intel TDX providers
- **Signing key handling**: hardware-sealed key generation, storage, and use; any path by which a signing key could be extracted or used outside the enclave
- **Cedar policy enforcement**: correctness of allow/deny decisions; policy bundle loading and hash verification inside the enclave; enforcement mode handling
- **Audit chain**: integrity of TRACE claim output fields (`policy_bundle_hash`, `audit_chain_root`, `tee_public_key`); any path by which a valid audit entry could be forged or suppressed
Expand Down
1 change: 0 additions & 1 deletion STATUS.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ picture is stated once. Developer Preview: interfaces may change before v1.0.
| Attestation verifiers: `sev-snp`, `tdx` | Shipped | Verified end to end against genuine hardware evidence: an Azure CVM SEV-SNP report (VCEK chain to the AMD ARK-Milan root, ECDSA-P384 report signature, paravisor `REPORT_DATA` binding) and a GCP C3 Intel TDX DCAP v4 quote (PCK chain to the pinned Intel SGX Root CA, QE binding, quote signature). Runs are recorded in [`docs/testing/hardware-validation.md`](docs/testing/hardware-validation.md). This validates the *verifier* against real quotes; quote generation still requires the corresponding hardware, and TCB status stays in `unverified_fields`. |
| Attestation verifier: `tpm` | Shipped in 0.4.0, with a host-dependent limit | **0.3.0 reported a forged TPM quote as hardware-attested and should not be used.** The `tpm2` branch of `verify_trace_claim` called only `verify_tpm_measurement`, which takes no signature parameter, so a `TPMS_ATTEST` with correct magic and matching `qualifying_data` passed with no signature and no chain (#370). `verify_tpm_quote_chained` existed and was hardware-validated on 2026-07-31 (an AK-signed quote from an Azure Trusted Launch vTPM verified end to end, tampered copies rejected, see [`docs/testing/hardware-validation.md`](docs/testing/hardware-validation.md)); nothing in production called it. Fixed in #469: the quote signature and the AK certificate chain now gate `hardware_attestation`, supplied-but-invalid material is fatal, and absent material degrades to `unverified` as SNP does. Signed evidence travels as `gateway.attestation_evidence`, which is why 0.4.0 is a break for older verifiers. **The remaining limit is the host, not the code (#453):** Azure Trusted Launch presents two AK certificate hierarchies concurrently at NV index `0x01C101D0`, and on the `Global Virtual TPM CA - 03` variant the AIA extension is absent entirely, so there is nothing to walk and no chain to a pinnable root. On such a host the chain cannot be established and the claim reports `unverified` rather than verified. Pin the root your own hosts present; a mixed fleet needs both. |
| TPM gateway NV measurement pair | Primitive shipped; runtime claim integration not shipped | Startup validates the exact configured `TPM_NT_EXTEND` public area and collects a bracketing NV-certify pair when a platform AK is available. The standalone verifier requires an out-of-band trusted Name, exact range, expected digest, nonce, root, and AK chain. The current TRACE schema and `verify_trace_claim` do not carry or appraise this pair, and policy reload does not refresh it. Direct appraisal proves one signed transition for an authorized template, not index-incarnation continuity, approved pre-history, safe code, or runtime enforcement. |
| `opaque` provider | Not implemented | Opt-in placeholder; excluded from auto-detect. Selecting it explicitly raises `ATTESTATION_PROVIDER_NOT_IMPLEMENTED` rather than falling through silently. |
| `gpu-cc` (NVIDIA H100/H200/Blackwell, via NRAS) | Planned (v0.2) | |
| Transparency-log anchoring for TRACE Claims | v0.2 | Write and lookup. |
| Server-side (provider) attestation | Not yet (Phase 2) | Phase 1 attests the gateway boundary only. |
Expand Down
7 changes: 2 additions & 5 deletions docs/SPEC.md
Original file line number Diff line number Diff line change
Expand Up @@ -260,12 +260,9 @@ Across the four problems and 13 shapes, Phase 1 covers 11 outright and partially
| tpm | TPM 2.0 / vTPM | Medium |
| sev-snp | AMD SEV-SNP (Azure DCasv5, AWS C6a Nitro) | High |
| tdx | Intel TDX (Azure DCedsv5, GCP C3) | High |
| opaque | OPAQUE Managed Runtime (opt-in; not yet implemented) | n/a |

Auto-detection probe order: `tpm -> sev-snp -> tdx`. The first provider whose `detect()`
succeeds is selected. `opaque` is a not-yet-implemented placeholder: it is excluded from
auto-detect, and selecting it explicitly raises `ATTESTATION_PROVIDER_NOT_IMPLEMENTED` rather
than falling through silently. If no hardware provider is detected, the gateway starts only
succeeds is selected. If no hardware provider is detected, the gateway starts only
under `CMCP_DEV_MODE=1` (a non-attested software-only fallback) and otherwise refuses to
start. Default `enforcement_mode` is `enforcing`.

Expand All @@ -291,7 +288,7 @@ In scope:
- Session-context sensitivity tagging and bleed detection
- Tool catalog binding (tool name to specific upstream server identity)
- TRACE Claim generation and signing
- Hardware attestation: TPM, SEV-SNP, TDX (OPAQUE Managed is an opt-in placeholder, not yet implemented)
- Hardware attestation: TPM, SEV-SNP, TDX
- Enforcement modes: enforcing, advisory, silent
- Egress policy: allow/deny/redact per tool and per field
- Per-session TRACE Claim with call summary
Expand Down
6 changes: 2 additions & 4 deletions docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ Most settings live in one file, `cmcp-config.yaml`. It says which secure hardwar

attestation:
# TEE provider. auto detects in order: azure-cvm -> tpm -> sev-snp -> tdx.
# opaque requires explicit opt-in via OPAQUE_ATTESTATION_URL env var.
# Use software-only only with CMCP_DEV_MODE=1.
provider: auto

Expand Down Expand Up @@ -90,7 +89,7 @@ policy_reload_interval_seconds: 0

| Field | Type | Default | Description |
|-------|------|---------|-------------|
| `provider` | string | `auto` | TEE provider. Valid values: `auto`, `tpm`, `sev-snp`, `tdx`, `opaque`, `software-only`. `auto` detects in order: azure-cvm, then tpm, then sev-snp, then tdx. `opaque` requires `OPAQUE_ATTESTATION_URL` to be set. `software-only` requires `CMCP_DEV_MODE=1`. |
| `provider` | string | `auto` | TEE provider. Valid values: `auto`, `tpm`, `sev-snp`, `tdx`, `software-only`. `auto` detects in order: azure-cvm, then tpm, then sev-snp, then tdx. `software-only` requires `CMCP_DEV_MODE=1`. |
| `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). |
Expand Down Expand Up @@ -150,7 +149,6 @@ Two of them decide who may approve a new policy while the gateway is running. `C
| `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 runtime HTTP auth. If set, all requests to the runtime must include `Authorization: Bearer <token>`. If unset, no bearer auth is enforced. This token is required for non-loopback binds. | none |
| `CMCP_OPERATOR_TOKEN` | Credential for the operator interface: `POST /sessions/{id}/reset` and `POST /catalog/exception`. Required outside `CMCP_DEV_MODE=1` (`OPERATOR_TOKEN_REQUIRED`), and must differ from `CMCP_BEARER_TOKEN`. When set, those two routes accept only this token and reject the tool-invocation token; when unset they fall back to `CMCP_BEARER_TOKEN`. A reset lowers accumulated session sensitivity, so an agent host holding only the tool-invocation token cannot clear the state that monotonicity exists to keep. | 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_POLICY_HASH` | SHA-256 hash of the approved policy bundle. Required in non-dev mode and checked by startup before Agent Manifest binding. The gateway fails closed at startup if this is unset and `CMCP_DEV_MODE` is not `1`. Format: `sha256:<hex>`. | none (startup policy integrity check) |
| `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:<hex>`. | none (additional startup check) |

Expand Down Expand Up @@ -209,5 +207,5 @@ configuration, classification assumptions, and the remaining audit/log limits.
- Set `CMCP_CATALOG_HASH` to the SHA-256 of the approved `catalog.json`. The gateway fails closed at startup if this is unset in non-dev mode, but setting it explicitly pins the approved catalog hash and prevents silent substitution.
- Configure `agent_manifest.path`, `agent_manifest.trust_anchor_path`, and `agent_manifest.authenticated_subject` for agents with signed manifests. The runtime will refuse to start if the signed manifest does not bind the authenticated agent subject to the loaded policy bundle and catalog hashes.
- Set `attestation.expected_measurement` to the expected TEE measurement for your deployment. Without this, a different binary could be deployed and would still produce valid attestation reports.
- Use a real TEE provider (`tpm`, `sev-snp`, `tdx`, or `opaque`), not `software-only`. Software-only mode has no hardware root of trust (nothing in the chip vouches for the software), and it leaves threat classes T1 through T4 in the [specification's threat model](SPEC.md#formal-threat-classes) open.
- Use a real TEE provider (`tpm`, `sev-snp`, or `tdx`), not `software-only`. Software-only mode has no hardware root of trust (nothing in the chip vouches for the software), and it leaves threat classes T1 through T4 in the [specification's threat model](SPEC.md#formal-threat-classes) open.
- Rotate the TEE signing key by performing a full enclave restart on a regular schedule. The signing key is hardware-sealed per enclave instance; rotation requires restart.
2 changes: 1 addition & 1 deletion docs/spec-index.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ Short definitions of terms used across these pages.
| Term | Definition |
|------|-----------|
| 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) |
| TEE | Trusted Execution Environment (TPM, SEV-SNP, or TDX) |
| 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 runtime decisions, signed with a TEE-sealed key |
Expand Down
Loading
Loading