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
10 changes: 5 additions & 5 deletions docs/SPEC.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
# cA2A Profile Specification

**Status**: draft, v0.1. This document describes the cA2A profile: a binding on A2A that makes agent-to-agent delegation attested, attenuated, confidential, and provable.
Status: draft, v0.1. This document describes the cA2A profile: a binding on A2A that makes agent-to-agent delegation attested, attenuated, confidential, and provable.

## Scope of this document

cA2A is a profile, not a transport. It does not define how tasks are moved between agents; A2A does that. It defines the trust envelope around a delegated task: what credential accompanies it, what a peer must prove before accepting it, how the payload is protected in transit and at rest in the peer, and what record is left behind.

## Design tenets

1. **Profile, not protocol.** Bind to A2A and to IETF RATS, EAT, and SCITT rather than reinvent them.
2. **Neutral by construction.** No coupling to a single silicon vendor, cloud, or AI platform. This is the claim a vendor-anchored verifier cannot make.
3. **Fail closed.** Absence of evidence is denial, not a warning. A missing attestation or an unverifiable chain denies the call.
4. **Offline verifiable.** A third party can verify a delegation chain and its provenance DAG without contacting or trusting any operator.
1. Profile, not protocol: Bind to A2A and to IETF RATS, EAT, and SCITT rather than reinvent them.
2. Neutral by construction: No coupling to a single silicon vendor, cloud, or AI platform. This is the claim a vendor-anchored verifier cannot make.
3. Fail closed: Absence of evidence is denial, not a warning. A missing attestation or an unverifiable chain denies the call.
4. Offline verifiable: A third party can verify a delegation chain and its provenance DAG without contacting or trusting any operator.

## Components

Expand Down
14 changes: 7 additions & 7 deletions docs/spec/attestation.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,25 +25,25 @@ An `AttestationReport` carries `platform`, `measurement`, the bound `public_key`

`ca2a_verify.sev_snp.verify_sev_snp_report` appraises an AMD SEV-SNP attestation report offline, in three fail-closed steps:

1. **Certificate chain.** The VCEK is verified up to a trusted AMD root (ARK) through `ARK -> ASK -> VCEK`. Each certificate must be validly issued by the next, and the root must match a trusted anchor by fingerprint.
2. **Report signature.** The ECDSA-P384 signature (stored as little-endian `r` and `s`) is verified against the VCEK public key over the report body (`report[:0x2A0]`).
3. **Binding.** The launch `measurement` and the `report_data` (which carries the runtime key and nonce) are checked against expected values.
1. Certificate chain: the VCEK is verified up to a trusted AMD root (ARK) through `ARK -> ASK -> VCEK`. Each certificate must be validly issued by the next, and the root must match a trusted anchor by fingerprint.
2. Report signature: the ECDSA-P384 signature (stored as little-endian `r` and `s`) is verified against the VCEK public key over the report body (`report[:0x2A0]`).
3. Binding: the launch `measurement` and the `report_data` (which carries the runtime key and nonce) are checked against expected values.

**What is validated.** The chain-verification path is exercised against the genuine AMD Milan ARK/ASK root chain fetched from AMD KDS (`tests/fixtures/sev_snp/`). The report-signature path is exercised end to end with a synthetic VCEK and report, because a genuine report plus VCEK pair requires real SEV-SNP hardware. Producing a report (`SevSnpProvider.attest`) fails closed off hardware (`AttestationUnsupported`).
What is validated. The chain-verification path is exercised against the genuine AMD Milan ARK/ASK root chain fetched from AMD KDS (`tests/fixtures/sev_snp/`). The report-signature path is exercised end to end with a synthetic VCEK and report, because a genuine report plus VCEK pair requires real SEV-SNP hardware. Producing a report (`SevSnpProvider.attest`) fails closed off hardware (`AttestationUnsupported`).

**Cross-operator use.** Two operators in separate trust domains each bind their sealed-channel public key into a report and verify the counterparty's report against a pinned golden measurement. This composes into mutual attestation, confidential cross-operator delegation (seal to the attested key), and binary-swap detection (a changed measurement is rejected), validated in software as claim C6. See the [call graph](call-graph.md) and the `claim6-cross-operator-attestation` experiment.
Cross-operator use. Two operators in separate trust domains each bind their sealed-channel public key into a report and verify the counterparty's report against a pinned golden measurement. This composes into mutual attestation, confidential cross-operator delegation (seal to the attested key), and binary-swap detection (a changed measurement is rejected), validated in software as claim C6. See the [call graph](call-graph.md) and the `claim6-cross-operator-attestation` experiment.

## TDX verification

`ca2a_verify.tdx.verify_tdx_quote` appraises an Intel TDX quote (DCAP, ECDSA-256) offline in four fail-closed steps: the PCK certificate chain is verified up to a trusted Intel root; the Quoting Enclave report is verified against the PCK; the attestation key is confirmed to be the one the QE report data commits to (SHA-256 of the key and the QE auth data); and the attestation key's signature over the quote body is verified, along with the launch measurement (MRTD) and report data.

**What is validated.** The chain-verification path accepts the genuine self-signed Intel SGX Root CA fetched from Intel (`tests/fixtures/tdx/`) and rejects an untrusted root. The multi-level signature path (PCK to QE report to attestation key to quote) is exercised end to end with a synthetic self-consistent quote, because a genuine quote requires a TDX guest. Byte offsets follow the Intel DCAP Quote v4 layout; end-to-end validation against a real hardware quote requires a TDX guest and remains open.
What is validated. The chain-verification path accepts the genuine self-signed Intel SGX Root CA fetched from Intel (`tests/fixtures/tdx/`) and rejects an untrusted root. The multi-level signature path (PCK to QE report to attestation key to quote) is exercised end to end with a synthetic self-consistent quote, because a genuine quote requires a TDX guest. Byte offsets follow the Intel DCAP Quote v4 layout; end-to-end validation against a real hardware quote requires a TDX guest and remains open.

## TPM verification

`ca2a_verify.tpm.verify_tpm_quote` appraises a TPM 2.0 quote (`TPMS_ATTEST`) offline: the AK certificate chain is verified to a trusted root, the AK signature over the attest blob is verified (ECDSA-SHA256 or RSA PKCS#1 v1.5), the structure is confirmed to be a TPM-generated quote (magic and type), and the qualifying data (the verifier's nonce) and the PCR digest (the platform measurement) are checked against expected values.

**What is validated.** Unlike SEV-SNP and TDX, TPM attestation keys chain to per-vendor EK roots, so there is no single published root to validate against; the caller supplies the vendor roots it trusts, and the verifier is exercised against synthetic self-consistent vectors. Producing a quote (`TpmProvider.attest`) fails closed off a real TPM.
What is validated. Unlike SEV-SNP and TDX, TPM attestation keys chain to per-vendor EK roots, so there is no single published root to validate against; the caller supplies the vendor roots it trusts, and the verifier is exercised against synthetic self-consistent vectors. Producing a quote (`TpmProvider.attest`) fails closed off a real TPM.

## Fail closed

Expand Down
12 changes: 6 additions & 6 deletions docs/spec/cedar-policy.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ When a peer accepts a delegated task, two independent trust decisions meet. The
effective = delegated_scope ∩ local_policy_allow
```

**Status.** The intersection semantics are **implemented** as an enforcement decision core in `ca2a_runtime.peer` (`effective_scope`, `enforce_peer_call`), and the local policy can be either a capability allow set (`ca2a_runtime.policy.LocalPolicy`) or a **real Cedar policy engine** (`ca2a_runtime.cedar.CedarPolicy`, backed by `cedarpy`, the same engine cMCP runs). Both satisfy the `ca2a_runtime.policy.Policy` protocol, so they are interchangeable in the peer path. Validated by experiment C3 and the Cedar unit tests. What remains is wiring the decision core to a **live A2A transport** rather than a direct call. See [call-graph.md](call-graph.md) and [ROADMAP.md](../../ROADMAP.md).
Status: the intersection semantics are implemented as an enforcement decision core in `ca2a_runtime.peer` (`effective_scope`, `enforce_peer_call`), and the local policy can be either a capability allow set (`ca2a_runtime.policy.LocalPolicy`) or a real Cedar policy engine (`ca2a_runtime.cedar.CedarPolicy`, backed by `cedarpy`, the same engine cMCP runs). Both satisfy the `ca2a_runtime.policy.Policy` protocol, so they are interchangeable in the peer path. Validated by experiment C3 and the Cedar unit tests. What remains is wiring the decision core to a live A2A transport rather than a direct call. See [call-graph.md](call-graph.md) and [ROADMAP.md](../../ROADMAP.md).

## Cedar policy

Expand All @@ -24,8 +24,8 @@ effective_scope(chain, policy) # delegated leaf scope AND what Cedar allows

Each side owns half of the decision, and neither may escalate the other.

- **Delegation is authoritative on the caller's side.** A capability that is allowed by the callee's local policy but absent from the verified delegated scope is dropped. The caller was never granted it upstream, so local policy cannot manufacture it.
- **Local policy is authoritative on the callee's side.** A capability present in the delegated scope but denied by local policy is dropped. The delegator cannot force the callee to honor something the callee's own policy forbids.
- Delegation is authoritative on the caller's side: a capability that is allowed by the callee's local policy but absent from the verified delegated scope is dropped. The caller was never granted it upstream, so local policy cannot manufacture it.
- Local policy is authoritative on the callee's side: a capability present in the delegated scope but denied by local policy is dropped. The delegator cannot force the callee to honor something the callee's own policy forbids.

The safe combination is therefore the set intersection, not a union and not an override. The effective set is never larger than either input. This is defense in depth: an error or compromise on one side cannot widen what the other side permits.

Expand Down Expand Up @@ -69,7 +69,7 @@ Today the field is validated by `Ca2aConfig.from_dict` but has no runtime effect

## Illustrative shape

The following shows the intended computation. It is **illustrative only** and is **not the Cedar engine**: it stands in a plain set intersection for what the runtime will do by mapping each capability to a Cedar authorization query. The `experiments/claim3-scope-policy-intersection/run.py` harness prints this same shape behind a SKIP banner, because the real path is gated on Tier 2.
The following shows the intended computation. It is illustrative only and is not the Cedar engine: it stands in a plain set intersection for what the runtime will do by mapping each capability to a Cedar authorization query. The `experiments/claim3-scope-policy-intersection/run.py` harness prints this same shape behind a SKIP banner, because the real path is gated on Tier 2.

```python
# Illustrative only. NOT the Cedar engine and NOT the runtime path.
Expand All @@ -92,7 +92,7 @@ In the wired implementation `local_policy_allow` is not a precomputed set. Each

The scope-policy intersection depends on two Tier 2 runtime pieces, neither of which is built:

- **Runtime peer-delegation enforcement.** A call-time gate that accepts a delegation credential on a live inbound peer call and runs verification in the request path. `verify_chain` already checks the chain in isolation; there is no point at which it gates an actual peer-to-peer call.
- **Cedar binding.** The wiring from a verified delegated scope to the cmcp Cedar engine, and the effective-permission computation above.
- Runtime peer-delegation enforcement: a call-time gate that accepts a delegation credential on a live inbound peer call and runs verification in the request path. `verify_chain` already checks the chain in isolation; there is no point at which it gates an actual peer-to-peer call.
- Cedar binding: the wiring from a verified delegated scope to the cmcp Cedar engine, and the effective-permission computation above.

Until both land, do not describe cA2A as enforcing local policy on delegated calls. See [ROADMAP.md](../../ROADMAP.md).
6 changes: 3 additions & 3 deletions docs/spec/conformance.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Conformance

An implementation may claim **cA2A-compatible** for a given version when it passes all MUST-level tests in the cA2A conformance suite for that version. This ties directly to the trademark language in [CHARTER.md](../../CHARTER.md): the mark asserts that a deployment satisfies the attestation, attenuation, sealing, and provenance requirements defined here.
An implementation may claim cA2A-compatible for a given version when it passes all MUST-level tests in the cA2A conformance suite for that version. This ties directly to the trademark language in [CHARTER.md](../../CHARTER.md): the mark asserts that a deployment satisfies the attestation, attenuation, sealing, and provenance requirements defined here.

## The normative suite

Expand All @@ -24,8 +24,8 @@ pytest tests/conformance/ -v

## Levels

- **MUST**: required for a cA2A-compatible claim. Partial conformance (MUST only) is sufficient.
- **SHOULD**: recommended; indicates a higher-quality implementation.
- MUST: required for a cA2A-compatible claim. Partial conformance (MUST only) is sufficient.
- SHOULD: recommended; indicates a higher-quality implementation.

Test IDs are stable: once assigned, an ID is never reused even if the test is removed. This lets a conformance report for one version be compared against another.

Expand Down
2 changes: 1 addition & 1 deletion docs/spec/failure-modes.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

cA2A fails closed. Every check on the delegation path either produces positive, verifiable evidence that a request is authorized, or it denies. There is no third state where a request proceeds with a warning attached. The guiding principle is this:

**Absence of evidence is denial, not a warning.**
Absence of evidence is denial, not a warning.

An unsigned credential, a measurement that cannot be checked, a provenance record whose parent link does not resolve: each of these is treated as a failure, not a soft signal. This page enumerates the failure paths, the error each one raises, and which paths are enforced today versus which fail closed pending Tier 2/3 work.

Expand Down
2 changes: 1 addition & 1 deletion docs/spec/threat-model.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,4 @@ Out of adversary scope: breaking the underlying cryptographic primitives (Ed2551

## Residual risks in this release

Because attestation and sealing are not yet implemented (Tier 2/3), this release defends bounded authority and provenance-of-intent (via signed chains) but does **not** yet defend peer integrity or task confidentiality at runtime. Do not rely on cA2A for confidentiality across a trust boundary until the sealed channel and a real attestation backend land. See [LIMITATIONS.md](../../LIMITATIONS.md).
Because attestation and sealing are not yet implemented (Tier 2/3), this release defends bounded authority and provenance-of-intent (via signed chains) but does not yet defend peer integrity or task confidentiality at runtime. Do not rely on cA2A for confidentiality across a trust boundary until the sealed channel and a real attestation backend land. See [LIMITATIONS.md](../../LIMITATIONS.md).
Loading