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
4 changes: 2 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- `POST /sessions/{id}/close` issues the signed TRACE Trust Record and rotates the session
- Cedar `@annotation` metadata returned as structured advice on deny decisions (HITL payloads)
- `cmcp-verify`: one-command verification of claims and signed audit bundles, tamper-evident
- Fail-closed hardware verifiers (TPM, SEV-SNP, TDX, Opaque): no attestation evidence means no verification
- Fail-closed hardware verifiers (TPM, SEV-SNP, TDX, OPAQUE): no attestation evidence means no verification
- Dev-mode records carry `platform: software-only`, never `tpm2` (requires `agentrust-trace>=0.1.1`)
- Silent mode contract: operational logs quiet, audit evidence always recorded

## [0.1.0] - 2026-06-09

### Added

- Initial TEE gateway with provider support for TPM, SEV-SNP, TDX, and Opaque
- Initial TEE gateway with provider support for TPM, SEV-SNP, TDX, and OPAQUE
- Cedar policy enforcement for request authorization at the gateway layer
- TRACE Claim generation using the `GatewayClaim` envelope from `agentrust-trace`
- `cmcp-verify` standalone verifier for validating TRACE Claims offline
Expand Down
4 changes: 2 additions & 2 deletions CHARTER.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ Out of scope: AI model governance beyond tool-call enforcement, hardware TEE pla

Upon host organization acceptance, governance transitions from the current Project Lead model to a Technical Steering Committee (TSC).

**Composition**: 3–7 members. No single organization may hold more than 40% of TSC seats. The founding Project Lead (Imran Siddique, Opaque Systems) holds one founding seat for the v1.0 release cycle.
**Composition**: 3–7 members. No single organization may hold more than 40% of TSC seats. The founding Project Lead (Imran Siddique, OPAQUE Systems) holds one founding seat for the v1.0 release cycle.

**Election**: TSC members are elected annually by active contributors (at least one merged pull request in the preceding 12 months). Each contributor has one vote.

Expand All @@ -51,7 +51,7 @@ Code and schemas are licensed under Apache 2.0 with Patent Promise (see LICENSE)

## 5. Trademark Policy

"cMCP" and "cMCP-compatible" as project and conformance marks are currently held by Opaque Systems, Inc. Upon host organization acceptance, trademark ownership transfers to AAIF under their standard trademark policy.
"cMCP" and "cMCP-compatible" as project and conformance marks are currently held by OPAQUE Systems, Inc. Upon host organization acceptance, trademark ownership transfers to AAIF under their standard trademark policy.

Use of "cMCP-compatible" to describe a gateway deployment requires that the implementation satisfies the hardware attestation and policy enforcement requirements defined in the project documentation for the version being claimed.

Expand Down
2 changes: 1 addition & 1 deletion GOVERNANCE.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ The project lead is responsible for the technical direction of cMCP, final say o

| Name | Affiliation | GitHub |
|------|-------------|--------|
| Imran Siddique | Opaque Systems | @imransiddique |
| Imran Siddique | OPAQUE Systems | @imransiddique |

The project lead role is subject to Foundation confirmation. Succession is decided by a 2/3 maintainer vote, ratified by the Foundation.

Expand Down
2 changes: 1 addition & 1 deletion LIMITATIONS.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ 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 |
| OPAQUE Managed | less than 50ms |
| software-only | negligible |

### Per-call gateway overhead
Expand Down
2 changes: 1 addition & 1 deletion MAINTAINERS.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

| Name | GitHub | Affiliation | Role |
|------|--------|-------------|------|
| Imran Siddique | @imransiddique | Opaque Systems | Project Lead |
| Imran Siddique | @imransiddique | OPAQUE Systems | Project Lead |

## Roles

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ 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) |
| `OPAQUE_ATTESTATION_URL` | Enable OPAQUE Managed Runtime attestation (explicit opt-in) |

---

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, Intel TDX, and OPAQUE Managed Runtime 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
2 changes: 1 addition & 1 deletion docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ 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 runtime per session |
| TEE | Trusted Execution Environment (TPM, SEV-SNP, TDX, or Opaque Managed) |
| 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 runtime decisions, signed with a TEE-sealed key |
Expand Down
4 changes: 2 additions & 2 deletions docs/SPEC.md
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ 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 | Highest |
| opaque | OPAQUE Managed Runtime | Highest |

Auto-detection: tpm -> sev-snp -> tdx -> opaque. Default enforcement_mode: advisory.

Expand All @@ -259,7 +259,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
- Hardware attestation: TPM, SEV-SNP, TDX, OPAQUE Managed
- Enforcement modes: enforcing, advisory, silent
- Egress policy: allow/deny/redact per tool and per field
- Per-session TRACE Claim with call summary
Expand Down
2 changes: 1 addition & 1 deletion docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ Environment variables control secrets and mode flags that must not appear in con
|----------|-------------|-----------|
| `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. | 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 |
| `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
8 changes: 4 additions & 4 deletions docs/spec/attestation.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,14 +95,14 @@ Each value is a 48-byte SHA-384 digest encoded as lowercase hex (96 characters).

The full TD report and quote are stored in `attestation_report.raw_evidence` for verifier use.

#### Opaque (Highest Assurance)
#### OPAQUE (Highest Assurance)

Detection conditions:
- The environment variable `OPAQUE_RUNTIME_ENDPOINT` is set and non-empty.

What goes in `attestation_report.measurement`:

The Opaque Managed Runtime provides a dedicated attestation API. The runtime calls `GET $OPAQUE_RUNTIME_ENDPOINT/v1/attestation` with the §3.3 nonce (`JWK_thumbprint(tee_public_key) || random_salt`) 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 §3.3 nonce (`JWK_thumbprint(tee_public_key) || random_salt`) 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

Expand Down Expand Up @@ -132,7 +132,7 @@ Rules:

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).
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 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.
Expand Down Expand Up @@ -318,7 +318,7 @@ Because the public key is embedded in the claim and attested by the hardware rep

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).
- 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.
- Rotation: updating the enclave's code or configuration changes its measurement. The old sealed key cannot be unsealed by the new measurement. The new enclave generates a fresh keypair and seals it to its own measurement. Old TRACE Claims remain verifiable via their embedded public key. New claims use the new key.
- A key rotation event should be logged in the operator's change management system.
Expand Down
2 changes: 1 addition & 1 deletion docs/spec/component-model.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ Closes #43.

**Owned by**: Enterprise deployer (Phase 1) or SaaS vendor (Phase 2, provider-side).

**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.
**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).
Expand Down
2 changes: 1 addition & 1 deletion docs/spec/transport.md
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ TEE boots
| TPM | PCR values | Platform Configuration Registers (PCR0-PCR7 minimum) contain hashed measurements of each boot component: firmware, bootloader, kernel, initrd. The SPIRE TPM plugin reads PCR values via the TPM2 TSS stack and verifies them against expected values. |
| SEV-SNP | SEV measurement | A SHA-384 hash of the encrypted VM memory contents at launch time, produced by the AMD PSP. The measurement covers the initial memory pages loaded into the encrypted VM. The SPIRE SEV-SNP plugin submits the measurement to AMD attestation service (or a self-hosted equivalent) for verification. |
| TDX | RTMR values | Runtime Measurement Registers (RTMR0-RTMR3) accumulate hashes of components loaded after the TD is created (analogous to TPM PCRs but for TDs). The SPIRE TDX plugin reads the RTMR values from the TD Quote and verifies them against expected values. |
| Opaque | Opaque Managed Runtime measurement | The Opaque platform produces a composite measurement of the enclave and its configuration. The SPIRE plugin delegates to the Opaque attestation API. |
| OPAQUE | OPAQUE Managed Runtime measurement | The OPAQUE platform produces a composite measurement of the enclave and its configuration. The SPIRE plugin delegates to the OPAQUE attestation API. |

### Validation Spike

Expand Down
8 changes: 4 additions & 4 deletions docs/spec/verification-library.md
Original file line number Diff line number Diff line change
Expand Up @@ -142,11 +142,11 @@ If any external evidence check fails, the audit bundle result is `verified=False
5. Confirm TD_REPORT.MRTD || RTMR0 || RTMR1 || RTMR2 || RTMR3 == attestation_report.measurement (concatenated).
6. If all checks pass: TEE identity is verified for TDX.

### Opaque Managed Verification
### OPAQUE Managed Verification

1. Call the Opaque attestation verification endpoint (provided at deployment time) with the attestation_report.raw_evidence as the request body.
1. Call the OPAQUE attestation verification endpoint (provided at deployment time) with the attestation_report.raw_evidence as the request body.
2. The endpoint returns: {verified: true|false, measurement_matched: true|false, error?: string}.
3. If verified and measurement_matched: TEE identity is verified for Opaque Managed.
3. If verified and measurement_matched: TEE identity is verified for OPAQUE Managed.

## What "partially_verified" means

Expand All @@ -171,7 +171,7 @@ VerificationError enum:

## Phase 1 support matrix

Phase 1 must support TPM and SEV-SNP at minimum. TDX is high priority for the first release. Opaque is handled by the managed runtime and does not require a separate implementation path.
Phase 1 must support TPM and SEV-SNP at minimum. TDX is high priority for the first release. OPAQUE is handled by the managed runtime and does not require a separate implementation path.

`SOFTWARE_ONLY` is a valid enum value for local development and CI environments. A claim with `provider: software-only` must always return `VerificationStatus.PARTIALLY_VERIFIED` with `failure_reason` set, never `VERIFIED`.

Expand Down
2 changes: 1 addition & 1 deletion docs/testing/benchmarks.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ Attestation is a startup cost, not a per-call cost. It is not included in the pe
| TPM | < 500ms | Hardware I/O bound; TPM attestation is slow |
| SEV-SNP | < 100ms | Azure DCasv5, AWS C6a Nitro |
| TDX | < 100ms | Azure DCedsv5, GCP C3 |
| Opaque Managed | < 50ms | Opaque Managed Runtime, highest assurance |
| OPAQUE Managed | < 50ms | OPAQUE Managed Runtime, highest assurance |

### Per-Call Runtime Overhead

Expand Down
4 changes: 2 additions & 2 deletions docs/tutorials/kill-switch.md
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ if result.status == "verified":
print("Agent was automatically blocked — hardware-attested enforcement confirmed.")
```

A verifier running offline — with no connection to the cMCP gateway or to Opaque — can confirm that:
A verifier running offline — with no connection to the cMCP gateway or to OPAQUE — can confirm that:

- The kill switch fired in this session (`kill_switch_triggered: true`)
- The policy that caused the denies is recorded by hash in `trace.policy.bundle_hash`
Expand Down Expand Up @@ -170,7 +170,7 @@ For UAE federal ministries and other sovereign deployments, `kill_switch_trigger

- The TEE signs the claim — the cloud operator and the ministry IT team cannot produce this artifact for a different outcome
- The audit chain entry records the agent identity, the deny rate window, and the trigger timestamp
- The claim is verifiable offline by the federal oversight body without calling back to any Opaque service
- The claim is verifiable offline by the federal oversight body without calling back to any OPAQUE service

This closes the regulatory gap that a log file cannot close: a log entry is something the operator controls. A TEE-signed TRACE claim with `kill_switch_triggered: true` is not.

Expand Down
2 changes: 1 addition & 1 deletion docs/tutorials/tee-attestation.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ The `provider` field in `cmcp-config.yaml` controls which TEE the runtime uses.
| `tpm` | TPM 2.0 chip present and accessible. |
| `sev-snp` | AMD SEV-SNP hardware. Requires `/dev/sev-guest` (device path is hardcoded; no env var override). |
| `tdx` | Intel TDX hardware. |
| `opaque` | Opaque Managed Runtime. Requires `OPAQUE_ATTESTATION_URL` env var. |
| `opaque` | OPAQUE Managed Runtime. Requires `OPAQUE_ATTESTATION_URL` env var. |
| `software-only` | No hardware. Requires `CMCP_DEV_MODE=1`. |

`software-only` is rejected at startup unless `CMCP_DEV_MODE=1` is set. Do not set `CMCP_DEV_MODE=1` in production.
Expand Down