diff --git a/LIMITATIONS.md b/LIMITATIONS.md index f8325bb..48b51b5 100644 --- a/LIMITATIONS.md +++ b/LIMITATIONS.md @@ -1,5 +1,30 @@ # Limitations +This page says what cA2A proves today, what it does not, and what is still being +built, so you can decide how much to rely on it. Read it before you rely on any +hardware claim. + +cA2A 0.4.0 (published as `ca2a-runtime`) is a developer preview with a runnable, +tested profile and runtime. This document states plainly what is built, what +remains before 1.0, and what is out of scope, so no claim in the documentation runs +ahead of the code. This is a deliberate discipline: proof, not promises. + +In short: + +- **Works offline today, no hardware needed:** checking that a chain of permissions + starts at an authority you trust and only narrows at each handoff, refusing + revoked grants when you supply a revocation list, encrypting a task to one agent, + and checking signed records of each handoff. +- **Checked on real hardware, with limits:** AMD SEV-SNP and Intel TDX reports from + real Azure and GCP machines; an Azure agent calling a GCP agent in one direction; + two GCP machines run by one operator checking each other in both directions. + Two machines run by different operators checking each other has not yet been shown. +- **Off unless you turn it on:** checking the platform settings inside a hardware + report (such as whether SMT is on), and authenticating the answer that comes back + from a call. +- **Not done at all:** publishing or fetching revocation data. A checker knows only + about the revocations in the snapshot you hand it. + ## Opt-in response authentication `send_task(require_authenticated_response=True)` authenticates readable @@ -11,8 +36,6 @@ MAC key. Hardware assurance still requires explicit hardware appraisal; the new profile has software/HTTP tests and no new live-hardware validation. See the [profile and deployment limits](docs/spec/response-authentication.md). -cA2A 0.2 is a Developer Preview with a runnable, tested profile and runtime. This document states plainly what is built, what remains before 1.0, and what is out of scope, so no claim in the documentation runs ahead of the code. This is a deliberate discipline: proof, not promises. - ## What is built - The delegation credential model and offline chain verifier: trusted-root checks, signatures, scope attenuation, depth and validity bounds, duplicate credential IDs within a chain, and cross-chain splice rejection. These checks do not maintain a global history of used credentials. diff --git a/README.md b/README.md index 1b693ad..978bd11 100644 --- a/README.md +++ b/README.md @@ -27,9 +27,11 @@ Community updates and contributor highlights: [AgenTrust on LinkedIn](https://ww [![PyPI](https://img.shields.io/pypi/v/ca2a-runtime)](https://pypi.org/project/ca2a-runtime/) -> **Developer Preview.** cA2A 0.2 ships the profile, offline verifier, enforced peer runtime, sealed channel, signed TRACE provenance, and fail-closed SEV-SNP, TDX, and TPM appraisal. It may still introduce breaking changes before 1.0. See [ROADMAP.md](ROADMAP.md) and [LIMITATIONS.md](LIMITATIONS.md) for the remaining hardware and interoperability work. +> **Developer Preview.** cA2A 0.4.0 ([`ca2a-runtime`](https://pypi.org/project/ca2a-runtime/) on PyPI) ships the profile, offline verifier, enforced peer runtime, sealed channel, signed TRACE provenance, and fail-closed SEV-SNP, TDX, and TPM appraisal. It may still introduce breaking changes before 1.0. See [ROADMAP.md](ROADMAP.md) and [LIMITATIONS.md](LIMITATIONS.md) for the remaining hardware and interoperability work. -**cA2A (Confidential A2A) is the secure, confidential way to do agent-to-agent delegation on the [Agent2Agent (A2A)](https://a2a-protocol.org/) protocol.** It layers attested, attenuated delegation, a sealed peer channel, and an offline-verifiable provenance record on top of A2A, without replacing the transport. If you are looking for a secure version of A2A for multi-agent systems, this is the AgenTrust profile for it. +**cA2A (Confidential A2A) lets one AI agent hand work to another on the [Agent2Agent (A2A)](https://a2a-protocol.org/) protocol and leaves proof of who allowed what.** Each handoff carries a signed permission slip that can only narrow, the receiving agent can be asked for a hardware-signed report of what software it runs (attestation), the task can be encrypted so only that agent can read it, and each step leaves a signed record anyone can check offline. It adds these to A2A without replacing how A2A sends messages. New to these terms? See [the plain-English glossary](https://agentrust-io.com/#plain-terms). + +In technical terms: cA2A layers attested, attenuated delegation, a sealed peer channel, and an offline-verifiable provenance record on top of A2A, without replacing the transport. If you are looking for a secure version of A2A for multi-agent systems, this is the AgenTrust profile for it. Agent A delegates a task to Agent B. B delegates part of it to C. Who authorized what? Did B stay inside the authority A actually held? Was the task payload readable by anyone between them? If a regulator asks, can you prove the answer for every hop? diff --git a/ROADMAP.md b/ROADMAP.md index 65f3dd0..cd83de5 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -1,5 +1,9 @@ # cA2A Roadmap +This page lists what cA2A has delivered, release by release, and what is left before +a stable 1.0. It is for anyone planning to adopt cA2A or contribute to it. For what +the current release does and does not prove, read [LIMITATIONS.md](LIMITATIONS.md). + cA2A is an extension of the agentrust-io stack, not a rewrite. The build tiers below track how much each piece leans on primitives that already exist in [agent-manifest](https://github.com/agentrust-io/agent-manifest), [cmcp](https://github.com/agentrust-io/cmcp), and [trace-spec](https://github.com/agentrust-io/trace-spec). ## Reused as-is (Tier 0) @@ -30,13 +34,14 @@ Already implemented and tested elsewhere; cA2A depends on it rather than reimple Real hardware attestation verification (SEV-SNP VCEK chain, Intel TDX quote via QVL/PCS, TPM AK cert + checkquote) is shared with cMCP. Appraisal against genuine SEV-SNP and TDX evidence has landed; the work below tracks what remains before broadly claiming mutual, cross-operator hardware assurance. -- **SEV-SNP verifier: landed and validated on real evidence.** Report parsing, VCEK chain verification, ECDSA-P384 report-signature verification, and measurement/report-data binding, all fail-closed, run against a genuine Azure CVM report (see [docs/hardware-validation.md](docs/hardware-validation.md)). Report generation is implemented via configfs-TSM but is not yet hardware-validated, and Azure's paravisor shape is out of scope for it. See `ca2a_verify.sev_snp` and [docs/spec/attestation.md](docs/spec/attestation.md). -- **TDX verifier: landed and validated on real evidence.** DCAP Quote v4 parsing (including the nested type-6 QE certification data), PCK chain to the genuine Intel SGX Root CA, QE report signature, attestation-key binding, quote signature, and MRTD binding, all fail-closed, run against a genuine GCP C3 quote. Quote generation is implemented via configfs-TSM but is not yet hardware-validated. See `ca2a_verify.tdx`. +- **SEV-SNP verifier: landed and validated on real evidence.** Report parsing, VCEK chain verification, ECDSA-P384 report-signature verification, and measurement/report-data binding, all fail-closed, run against a genuine Azure CVM report (see [docs/hardware-validation.md](docs/hardware-validation.md)). Report generation is implemented via configfs-TSM and was run on real silicon on 2026-08-24 (GCP `n2d-standard-4`, AMD Milan); Azure's paravisor shape is out of scope for it. See `ca2a_verify.sev_snp` and [docs/spec/attestation.md](docs/spec/attestation.md). +- **TDX verifier: landed and validated on real evidence.** DCAP Quote v4 parsing (including the nested type-6 QE certification data), PCK chain to the genuine Intel SGX Root CA, QE report signature, attestation-key binding, quote signature, and MRTD binding, all fail-closed, run against a genuine GCP C3 quote. Quote generation is implemented via configfs-TSM and was run on real silicon on 2026-08-24 (GCP `c3-standard-4`). See `ca2a_verify.tdx`. - **TPM 2.0 verifier: landed.** TPMS_ATTEST parsing, AK chain to a caller-supplied vendor root, AK signature (ECDSA or RSA), magic/type checks, and qualifying-data/PCR-digest binding, all fail-closed. Quote generation requires a real TPM. See `ca2a_verify.tpm`. - **Cross-operator attestation (C6): validated in software.** A two-operator harness (SEV-SNP verifier + measurement pinning + sealed channel) shows independent keys, mutual attestation, confidential cross-operator delegation, and binary-swap detection. All six claims (C1-C6) are now validated experiments. - **Live attested peer: landed.** The `verifier` seam has been driven off a real SEV-SNP quote on an Azure confidential VM, so `verify_offer` returned `assurance="hardware"` and a payload was sealed to a hardware-vouched channel key; measurement mismatch and stale nonce both rejected. See [docs/hardware-validation.md](docs/hardware-validation.md). - **Cross-operator, cross-TEE run: landed.** An Azure SEV-SNP peer appraised a GCP Intel TDX peer's real quote, sealed a delegated task to the attested key, and the TDX enclave opened it, enforced the attenuated scope, allowed `tool:search` and refused `tool:purchase` with a denial record returned across the boundary. See [docs/hardware-validation.md](docs/hardware-validation.md). -- **Pending:** a hardware run of the SEV-SNP and TDX collectors (both implemented against configfs-TSM, neither yet exercised on silicon), mutual attestation on real silicon in both directions (the protocol now supports it in software mode and is off by default; that hardware run was one-directional), simultaneous attestation (which needs a commitment step neither peer can back out of, a larger protocol than what landed), and the TPM certificate-chain path. TPM parsing, bindings and the AK signature are validated against a real Azure vTPM quote; SEV-SNP and TDX appraisal of real evidence is done. The transport that parses A2A messages into a `PeerRequest` has **landed** (`ca2a_runtime.transport.a2a_adapter`), running in software mode; the hardware seam is the `verifier` callable in `ca2a_runtime.attestation`. +- **Collectors on silicon: landed 2026-08-24.** Both the SEV-SNP and TDX collectors produced real evidence on GCP that this codebase's own verifiers appraised to the vendor roots. See [docs/hardware-validation.md](docs/hardware-validation.md). +- **Pending:** mutual attestation on real silicon across operators (on 2026-09-17 two GCP SEV-SNP guests in one project under one operator appraised each other in both directions; see [the mutual hardware procedure](docs/mutual-hardware-acceptance.md); the protocol is off by default), simultaneous attestation (which needs a commitment step neither peer can back out of, a larger protocol than what landed), and the TPM certificate-chain path. TPM parsing, bindings and the AK signature are validated against a real Azure vTPM quote; SEV-SNP and TDX appraisal of real evidence is done. The transport that parses A2A messages into a `PeerRequest` has **landed** (`ca2a_runtime.transport.a2a_adapter`), running in software mode; the hardware seam is the `verifier` callable in `ca2a_runtime.attestation`. ## v1.0 exit criteria: Stable profile diff --git a/docs/SPEC.md b/docs/SPEC.md index bda1405..3761033 100644 --- a/docs/SPEC.md +++ b/docs/SPEC.md @@ -1,5 +1,7 @@ # cA2A Profile Specification +This is the front page of the cA2A specification: the rules an implementation follows so that one AI agent can hand work to another with a checkable permission, hardware proof, an encrypted task and a signed record of each handoff. Implementers and reviewers start here; it lists the design principles and links to each part of the rules. + 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 diff --git a/docs/concepts.md b/docs/concepts.md index da60976..9039da4 100644 --- a/docs/concepts.md +++ b/docs/concepts.md @@ -1,32 +1,34 @@ # How It Works -cA2A layers delegation and peer trust checks onto A2A communication. Start with the [offline chain example](quickstart.md) to see grant validation; the live runtime adds caller authentication, local policy, optional appraisal, and payload handling. +This page explains, in order, what cA2A checks when one agent hands work to another, and where each check's protection stops. Read it after the [offline chain example](quickstart.md), which shows the first check on its own. A live call between agents adds more: confirming who the caller is, applying the receiving agent's own rules, optionally checking hardware proof, and handling the encrypted task. ## The gap cA2A closes -A signed identity document does not establish every authority or runtime property needed for a delegated task. The relying party must decide which root issuers, capabilities, measurements, and evidence it accepts. See the [threat model](spec/threat-model.md). +A signed identity document says who an agent is. It does not say what that agent may do on someone else's behalf, or what software it is actually running. The agent receiving the work (the relying party) has to decide for itself which starting authorities, permissions, hardware measurements and evidence it accepts. The [threat model](spec/threat-model.md) lists the attacks this guards against. ## The four primitives ### 1. Attenuated delegation -Each child grant is signed by the parent subject and must narrow or preserve the parent's scope. Verification checks trusted roots, signatures, parent links, credential IDs, depth, and validity windows. A valid chain establishes a grant; it does not authenticate the caller currently presenting it. The live path separately checks proof of possession of the leaf key. See [delegation chains](spec/delegation-chain.md). +"Attenuated" means the permission can only stay the same or get smaller at each handoff. Each child grant is signed by the agent that received the parent grant, and its scope (its list of permissions) must fit inside the parent's. The checker confirms the chain starts at a trusted root and that signatures, parent links, credential IDs, chain length and time windows are all valid. + +A valid chain proves a grant was made. It does not prove that whoever is presenting it right now is the agent it was given to, so on a live call cA2A also asks the caller to prove it holds the final agent's private key. See [delegation chains](spec/delegation-chain.md). ### 2. Runtime attestation -A provider produces evidence intended to bind a key to a measured runtime. The relying party must verify that evidence and apply its own measurement and assurance requirements. Software evidence does not establish hardware provenance. See [attestation](spec/attestation.md) and [limitations](../LIMITATIONS.md). +Attestation is a report, signed by the processor, that says what software is running and ties the agent's encryption key to it. A provider (the part of cA2A that talks to TPM, AMD SEV-SNP or Intel TDX hardware) produces that report. The relying party checks it and applies its own rules about which measurements and how much assurance it requires. A report produced in software mode proves nothing about hardware. See [attestation](spec/attestation.md) and [limitations](../LIMITATIONS.md). ### 3. Sealed peer channel -The caller encrypts a payload to the callee's appraised channel key. Hardware isolation depends on the verified provider and key binding. In software mode, this does not protect the key or plaintext from a privileged host. See [sealed channels](spec/sealed-channel.md). +The caller encrypts the task to a key the receiving agent (the callee) published and the caller checked, so only the holder of the matching private key can read it. Whether that key is protected by hardware depends on the hardware report that vouched for it. In software mode, an administrator of the machine could still read the key and the task. See [sealed channels](spec/sealed-channel.md). ### 4. Provenance record -Linked TRACE records carry the decision and parent references. Verifiers check signatures and links separately from credential-chain validation. The offline grant example does not execute a task or establish a provenance DAG. See [the TRACE A2A profile](spec/trace-a2a-profile.md). +Each handoff leaves a signed TRACE record of the decision, pointing back to the record before it, so the records together show the path the work took. Checking those records is separate from checking the permission chain. The offline grant example does not run a task or produce these records. See [the TRACE A2A profile](spec/trace-a2a-profile.md). ## How they compose on a peer call -The diagram follows the callee's inbound runtime checks. It shows the accepted path; a failed required check stops processing before payload opening. +The diagram follows the checks the receiving agent runs on an incoming call, in order. It shows the path when everything passes; a failed required check stops the call before the task is decrypted. Scroll the diagram horizontally on smaller screens. The text below explains the same boundaries. @@ -52,12 +54,15 @@ flowchart TB -Before sending a sealed payload, the caller must obtain and appraise the callee's channel offer. That outbound step and the callee's appraisal of the caller are distinct directions. The runtime box is a process boundary in software mode; verified confidential-computing deployments can add hardware isolation. The surrounding agents and their tools do not automatically move inside it. +Before sending an encrypted task, the caller first fetches and checks the callee's key offer. That check (the caller checking the callee) is separate from the callee checking the caller. In software mode the runtime box in the diagram is just a separate process; on verified confidential-computing hardware it can also be hardware-isolated. The agents and tools around it do not move inside it automatically. + +What the caller may actually do is the overlap of what it was delegated and what the callee's own rules allow. A delegation cannot grant something the callee's rules refuse. -The effective authority is the intersection of the delegated scope and local policy. Delegation cannot grant a capability that local policy refuses. Invalid chains or holder proofs are rejected before policy decisions and do not receive signed denial records; authenticated policy and appraisal denials have their own evidence behavior. See the [peer implementation](https://github.com/agentrust-io/ca2a/blob/main/src/ca2a_runtime/peer.py) for the exact ordering and failure paths. +??? info "Technical detail: denial records and ordering" + Invalid chains or holder proofs are rejected before policy decisions and do not receive signed denial records; authenticated policy and appraisal denials have their own evidence behavior. See the [peer implementation](https://github.com/agentrust-io/ca2a/blob/main/src/ca2a_runtime/peer.py) for the exact ordering and failure paths. ## Profile, not protocol -The profile defines trust fields and checks. The reference HTTP transport makes the peer path runnable, and an A2A SDK bridge is also available. Transport choice does not establish hardware assurance or replace the relying party's trust policy. +cA2A is a profile: a set of extra fields and checks added to A2A messages. It does not replace A2A's way of sending messages. A small reference web server ships so you can run the whole path, and a bridge to the official A2A software development kit is also available. Which transport you use does not add hardware assurance or replace the relying party's own trust rules. Continue with [configuration](configuration.md), the [profile](spec/profile.md), or the [limitations](../LIMITATIONS.md). diff --git a/docs/configuration.md b/docs/configuration.md index 40ab9c3..95de021 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -1,9 +1,14 @@ # Configuration -The cA2A runtime reads a YAML config. Offline commands validate it with -`ca2a validate-config`. `ca2a start` consumes the same file to build a -[`PeerNode`](spec/component-model.md) and serve it over the reference HTTP -transport. +This page is for operators who run a cA2A agent and need to set it up. One +settings file decides which starting authorities the agent trusts, what it will +allow callers to do, whether it asks callers for hardware proof, and where it +listens. Every setting is listed below with its default. + +The file is YAML. `ca2a validate-config` checks it without starting anything. +`ca2a start` reads the same file to build a +[`PeerNode`](spec/component-model.md) (one running cA2A agent) and serve it over +the reference HTTP transport. ## Reference @@ -34,6 +39,11 @@ local_policy: ["read", "write"] # allow-set for scope intersection (or use Ced ## Fields +The settings most people change first are `trusted_root_issuers` (whose permission +chains this agent accepts), `local_policy` (what this agent allows, whatever the +chain says) and `require_caller_attestation` (whether a caller must send hardware +proof). + | Field | Default | Description | |---|---|---| | `attestation.provider` | `auto` | TEE provider for peer attestation. `auto` selects a detected hardware provider and fails if there is none; it never falls back to `software-only`, which has to be named explicitly. `opaque` is not implemented. | diff --git a/docs/hardware-validation.md b/docs/hardware-validation.md index 699c7cb..9731eac 100644 --- a/docs/hardware-validation.md +++ b/docs/hardware-validation.md @@ -1,6 +1,12 @@ # Hardware validation -What `ca2a_verify` has been run against real confidential-computing hardware, +Confidential-computing processors from AMD (SEV-SNP), Intel (TDX) and TPM security +chips can sign a report saying what software a machine is running. This page is the +record of which of those real reports cA2A has checked, on which cloud machines and +on which dates, and what is still unproven. It is for anyone deciding how far to +trust cA2A's hardware claims, and for engineers who want to repeat a run. + +In detail: what `ca2a_verify` has been run against real confidential-computing hardware, what it has not, and how to reproduce each run. [LIMITATIONS.md](../LIMITATIONS.md) and [ROADMAP.md](../ROADMAP.md) link here rather than restating it. @@ -16,7 +22,8 @@ and the run is recorded below. | Intel TDX (GCP C3, non-paravisor) | Yes | Yes, to the real Intel SGX Root CA | Yes | **Yes**, 2026-07-27, capture of 2026-07-21 | | TPM 2.0 (Azure vTPM, Trusted Launch) | Yes | Yes, to a caller-supplied vendor root | Yes | **Partly**, 2026-07-27. Parse, bindings and AK signature yes; certificate chain no, see below | -That table is about *appraisal*. Collection is a separate axis, and a verifier validated on real evidence says nothing about whether this codebase can produce that evidence: +That table is about *appraisal*: checking a report someone hands you. Collection, +getting the machine to produce the report in the first place, is a separate axis, and a verifier validated on real evidence says nothing about whether this codebase can produce that evidence: | Platform | Collector | Run on real silicon | |---|---|---| @@ -225,7 +232,7 @@ CA2A_SNP_FIXTURE_DIR= pytest tests/unit/test_sev_snp.py ``` where the SNP directory holds `snp_report.bin`, `vcek.der`, and a -`cert_chain.pem` carrying **ASK then ARK only** — the test prepends the VCEK +`cert_chain.pem` carrying **ASK then ARK only**: the test prepends the VCEK itself, so including it in the PEM duplicates the leaf and the chain fails to verify. diff --git a/docs/mutual-hardware-acceptance.md b/docs/mutual-hardware-acceptance.md index 2e25912..6759cd9 100644 --- a/docs/mutual-hardware-acceptance.md +++ b/docs/mutual-hardware-acceptance.md @@ -1,5 +1,10 @@ # Mutual hardware acceptance run +This page records a test where two confidential-computing machines each checked the +other's hardware report before exchanging a task, and explains how to repeat it. It +is for engineers reproducing the run and for reviewers who want to know exactly what +it did and did not prove. + Status: a same-project live diagnostic completed on two GCP SNP guests on September 17, 2026. Calls succeeded in both directions, with separately collected receiver logs and matching nonsecret payload digests. A paced run passed one diff --git a/docs/quickstart.md b/docs/quickstart.md index 2c9c409..94a35f7 100644 --- a/docs/quickstart.md +++ b/docs/quickstart.md @@ -1,6 +1,8 @@ # Verify your first delegation chain -Build a two-hop grant: a root gives an intermediary `read` and `write`, and the intermediary gives the leaf only `read`. Verify it, then reject an untrusted root and a correctly signed grant that exceeds its parent's authority. After installation, this example needs no network, hardware, or running peer. +This page is for anyone who wants to see cA2A's core check working on their own computer. You build a chain of two handoffs: a starting authority (the root) gives a middle agent permission to `read` and `write`, and the middle agent passes only `read` on to a final agent (the leaf). You then check the chain, and watch it refuse two bad cases: a root you never agreed to trust, and a correctly signed grant that asks for more than its parent had. + +After installation, this example needs no network, no special hardware, and no running agents. ## Install @@ -83,7 +85,7 @@ Saved demo-chain.json and trusted-root.txt; private keys were not saved ## Verify it -Use the separately retained issuer key: +Check the saved chain with the command-line tool. You pass in the root key you kept separately, which is how the checker knows which starting authority you trust: ```bash ca2a verify-chain --chain demo-chain.json --trusted-root-issuer "$(cat trusted-root.txt)" @@ -95,21 +97,21 @@ Expected exit code: `0`. {"verified": true, "hops": 2, "leaf_scope": ["cap:read"], "revocation": "not_checked"} ``` -In production, the relying party obtains trusted roots through its own approval process. Copying the issuer from an arbitrary incoming chain into the trust list would let that chain choose its own authority. +In real use, the agent receiving the work (the relying party) decides which roots to trust through its own approval process. Copying the root out of an incoming chain and trusting it would let that chain choose its own authority. ## Try to break it -The script signs an overbroad child credential and expects `SCOPE_ESCALATION`. Editing a signed JSON field instead should fail the signature check first. These are different checks; an invalid signature does not demonstrate scope attenuation. +The script signs a child grant that asks for more than its parent had, and expects `SCOPE_ESCALATION` (scope is the list of permissions in a grant). If you instead edit a field in the saved JSON by hand, the signature check fails first. These are two different checks: a broken signature shows the file was changed, while the scope check shows a correctly signed grant still cannot widen its own permissions. -The verifier also checks issuer-to-subject continuity, parent links, unique credential IDs, depth, and validity windows. These offline checks do not keep a global ledger of previously accepted requests. Live request replay handling is a separate runtime concern. +The checker also confirms that each grant was issued by the agent the previous grant was given to, that parent links and credential IDs line up, that the chain is not too long, and that each grant is inside its valid time window. It does not keep a list of every request it has seen before; stopping a live request from being replayed is a separate job for the running service. ## Build a chain in code -The complete script above uses the same `DelegationCredential` and `verify_chain` APIs as the runtime. `trusted_root_issuers` is required for a successful verification. Keep the root grant and each child grant bounded by your own authorization policy. +The script above uses the same `DelegationCredential` and `verify_chain` functions the running service uses. `trusted_root_issuers` is required: with no trusted root, nothing verifies. Keep the root grant and each child grant within your own authorization rules. ## What is not in this walkthrough -This example verifies signed grants. It does not execute tasks, appraise hardware, seal a network payload, or verify a TRACE provenance DAG. Follow [How It Works](concepts.md) for the live peer path and [Limitations](../LIMITATIONS.md) for the evidence that has been demonstrated. +This example checks signed grants only. It does not run a task, check hardware, encrypt a task for another agent, or check the signed records each handoff leaves (the TRACE provenance chain). Read [How It Works](concepts.md) for what happens on a live call between agents, and [Limitations](../LIMITATIONS.md) for what has been shown on real hardware. ## Troubleshooting diff --git a/docs/spec/attestation.md b/docs/spec/attestation.md index cd69254..3b0ba54 100644 --- a/docs/spec/attestation.md +++ b/docs/spec/attestation.md @@ -1,4 +1,6 @@ # Peer Attestation + +Attestation is a report signed by the processor that says what software a machine is running. This page specifies how a cA2A agent produces such a report for TPM, AMD SEV-SNP and Intel TDX hardware, ties its encryption key to it, and how the other side checks it. It is for implementers and security reviewers; for a plain overview read [How It Works](../concepts.md). Before a peer is trusted with a delegated task, it proves it is running attested, measured code. cA2A reuses the pluggable TEE provider abstraction from [cmcp](https://github.com/agentrust-io/cmcp). diff --git a/docs/spec/call-graph.md b/docs/spec/call-graph.md index 1fc079c..f26db4b 100644 --- a/docs/spec/call-graph.md +++ b/docs/spec/call-graph.md @@ -1,5 +1,7 @@ # Inbound Peer-Call Decision +When a call arrives from another agent, cA2A runs a fixed series of checks before the application sees the task. This page lists those steps in order, what each needs, and where a failure stops the call. It is for implementers and anyone auditing what a cA2A agent accepts. + The inbound handler checks a caller's authority and identity before returning a task payload to the application. The reference HTTP transport and `PeerNode` use this handler; the profile does not mandate that transport. ## Decision flow diff --git a/docs/spec/cedar-policy.md b/docs/spec/cedar-policy.md index f9cf75c..1c7f675 100644 --- a/docs/spec/cedar-policy.md +++ b/docs/spec/cedar-policy.md @@ -1,5 +1,7 @@ # Scope-Policy Intersection (Cedar) +A permission handed down a chain is only usable if the receiving agent's own rules also allow it. This page explains how cA2A combines the two, either with a simple list of allowed actions or with Cedar, an open-source policy language. It is for operators writing those rules. + A delegated capability is usable only when the callee's local policy also allows it. The runtime implements this intersection with either `LocalPolicy`, a capability allow set, or `CedarPolicy`, backed by `cedarpy`. Both implement the `Policy` protocol and run in the live peer path. ```text diff --git a/docs/spec/component-model.md b/docs/spec/component-model.md index 8491432..1dbde76 100644 --- a/docs/spec/component-model.md +++ b/docs/spec/component-model.md @@ -1,5 +1,7 @@ # Component Model +This page maps each part of cA2A to the code module that implements it. It is for developers who want to read or extend the reference implementation. + cA2A composes delegation verification, local policy, caller authentication, attestation, encrypted payloads, and evidence records. The reference runtime and HTTP transport implement this path; hardware assurance depends on the provider and evidence available in the deployment. ## Components diff --git a/docs/spec/conformance.md b/docs/spec/conformance.md index bc87c58..24574a4 100644 --- a/docs/spec/conformance.md +++ b/docs/spec/conformance.md @@ -1,5 +1,7 @@ # Conformance +Conformance means passing the test suite that shows an implementation follows the cA2A rules. This page explains what the suite covers, how to run it, and what an implementation must pass before calling itself cA2A-compatible. + 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 diff --git a/docs/spec/delegation-chain.md b/docs/spec/delegation-chain.md index 73334e4..039c607 100644 --- a/docs/spec/delegation-chain.md +++ b/docs/spec/delegation-chain.md @@ -2,6 +2,8 @@ # Delegation Chain +A delegation chain is the list of signed permission slips that shows who handed which permissions to whom, starting from an authority you trust. This page gives the exact format of each slip and every rule a checker applies. It is for implementers; the [quick start](../quickstart.md) shows the same checks running. + A delegation chain is a root-to-leaf list of signed credentials. It is the primitive that lets Agent A hand a bounded slice of its authority to B, and B a still-smaller slice to C, with each grant provably within the one above it. diff --git a/docs/spec/error-codes.md b/docs/spec/error-codes.md index e4b77c7..0d642ff 100644 --- a/docs/spec/error-codes.md +++ b/docs/spec/error-codes.md @@ -1,4 +1,6 @@ # Error Codes + +Every refusal in cA2A has a stable code, such as `SCOPE_ESCALATION` when a grant asks for more than its parent had. This page lists every code, the HTTP status it maps to, and when it is raised. Developers use it to handle failures in code and tests. Every failure the cA2A runtime and verifier raise is a subclass of `CA2AError`. Each subclass carries a stable `code` string and an `http_status`. The code is what you match on in tests and callers. The HTTP status is what a service should return when the error crosses an A2A boundary. Both are defined in `ca2a_runtime/errors.py` and are the authoritative values below. diff --git a/docs/spec/failure-modes.md b/docs/spec/failure-modes.md index dde802f..afb9458 100644 --- a/docs/spec/failure-modes.md +++ b/docs/spec/failure-modes.md @@ -1,5 +1,7 @@ # Failure Modes +This page lists what happens when each check on an incoming call fails: which error is raised, how far the call gets, and whether a signed refusal record is produced. It is for operators and reviewers who need to know how cA2A behaves when something is wrong. + The full peer handler raises a `CA2AError` subtype when a required check fails and returns no payload. The configured caller-attestation requirement determines whether an absent offer is acceptable. The default permits absence and records `not_offered`; it never accepts a present but invalid offer. ## Inbound failures diff --git a/docs/spec/mutual-attestation.md b/docs/spec/mutual-attestation.md index a08b363..866bb58 100644 --- a/docs/spec/mutual-attestation.md +++ b/docs/spec/mutual-attestation.md @@ -6,6 +6,8 @@ Written: 2026-08-09 Stability: Unstable --- +Mutual attestation means both agents prove what they are running to each other, rather than only the caller checking the agent it calls. This page records how cA2A lets the receiving agent check the caller's hardware report too, and what that still does not cover. It is for implementers and security reviewers. + > **State of this document.** The design below is built. The callee issues a > challenge on the handshake endpoint, the caller binds its own channel key into a > report under it, and the callee appraises that before it opens the sealed @@ -167,7 +169,7 @@ A challenge is worth nothing unless it is single-use and expiring, and the reference server currently keeps no state at all. **Option A: a challenge store.** Issue random challenges, remember them, delete on -use, expire on a timer. Straightforward, and it makes the server stateful — which +use, expire on a timer. Straightforward, and it makes the server stateful, which matters for anyone running more than one instance, because a challenge issued by one is unknown to the next. diff --git a/docs/spec/profile.md b/docs/spec/profile.md index 94fc071..d28849b 100644 --- a/docs/spec/profile.md +++ b/docs/spec/profile.md @@ -1,5 +1,7 @@ # A2A Profile Binding +This page is the formal statement of what cA2A adds to A2A, the protocol agents use to talk to each other, and where each addition attaches. It is written for implementers and standards reviewers, in the precise MUST and SHOULD language that specifications use. + cA2A binds to A2A v1.x as an overlay. This page states normatively what the profile adds and where it attaches, without modifying A2A itself. ## Requirements language @@ -64,9 +66,9 @@ The rule behind that list: **every field of the request that reaches the emitted Holder binding MUST be evaluated after chain verification, so the subject is a key someone was genuinely delegated rather than one the caller asserted, and before the effective scope is computed under P-5, so a caller that has proved nothing never reaches policy evaluation and never elicits a signed denial record. -**This is not P-6.** Appraising a caller establishes what it is *running*; holder binding establishes *whose authority it holds*. The two are independent and neither implies the other: a caller can present a flawless `caller_offer`, appraise at hardware assurance, and still be exercising a chain issued to somebody else, because an attested runtime is not a claim to anyone's delegated authority. Without P-4a a chain is a bearer credential, and chains are published deliberately — handed to auditors for offline verification under P-8, embedded in provenance DAGs, and shipped as fixtures. +**This is not P-6.** Appraising a caller establishes what it is *running*; holder binding establishes *whose authority it holds*. The two are independent and neither implies the other: a caller can present a flawless `caller_offer`, appraise at hardware assurance, and still be exercising a chain issued to somebody else, because an attested runtime is not a claim to anyone's delegated authority. Without P-4a a chain is a bearer credential, and chains are published deliberately: handed to auditors for offline verification under P-8, embedded in provenance DAGs, and shipped as fixtures. -The binding key is already in the credential and needs no new trust root: `subject` is an Ed25519 public key whose private half the delegate must hold in order to issue child credentials, and before this it was only ever compared as a string for continuity. The proof commits to the caller's offered channel key so that, when both mechanisms are in play, the attested runtime and the delegated principal are provably the same party — which neither mechanism establishes alone. This is the RFC 7800 `cnf` pattern, matching what the TRACE layer already applies to provenance records. +The binding key is already in the credential and needs no new trust root: `subject` is an Ed25519 public key whose private half the delegate must hold in order to issue child credentials, and before this it was only ever compared as a string for continuity. The proof commits to the caller's offered channel key so that, when both mechanisms are in play, the attested runtime and the delegated principal are provably the same party, which neither mechanism establishes alone. This is the RFC 7800 `cnf` pattern, matching what the TRACE layer already applies to provenance records. A callee MAY accept a chain without a proof only for offline replay of recorded evidence, where no live caller exists to answer a challenge. It MUST NOT do so on a live peer path. @@ -82,7 +84,7 @@ Before accepting a delegated task across a trust boundary, a peer SHOULD be requ > Met one-directionally as of 2026-07-27. Driven off a live SEV-SNP quote on a running confidential VM, `verify_offer` returned `assurance="hardware"` and a payload was sealed to a channel key that a hardware-verified measurement vouches for. A cross-operator, cross-TEE run followed: an Azure SEV-SNP peer calling a GCP Intel TDX peer. > -> Two limits remain, and P-6 is not fully met until both close. **On hardware the appraisal is still one-directional**: in the recorded runs the caller appraised the callee and not the reverse, so neither side has yet proven itself to a peer that is simultaneously proving itself back. The protocol no longer is: as of 2026-08-09 a callee issues a challenge and appraises the caller's offer before opening the sealed payload, off by default and in software mode only ([mutual-attestation](mutual-attestation.md)). Making the protocol mutual does not make the recorded hardware run mutual, and it does not make the exchange simultaneous — the caller still commits a sealed payload before the callee has appraised it. And the committed harness in `examples/` still runs software-attested against synthetic vectors, because genuine evidence embeds per-CPU identifiers and is not shippable as a fixture. See [attestation](attestation.md) and [hardware-validation](../hardware-validation.md). +> Two limits remain, and P-6 is not fully met until both close. **On hardware the appraisal is still one-directional**: in the recorded runs the caller appraised the callee and not the reverse, so neither side has yet proven itself to a peer that is simultaneously proving itself back. The protocol no longer is: as of 2026-08-09 a callee issues a challenge and appraises the caller's offer before opening the sealed payload, off by default and in software mode only ([mutual-attestation](mutual-attestation.md)). Making the protocol mutual does not make the recorded hardware run mutual, and it does not make the exchange simultaneous: the caller still commits a sealed payload before the callee has appraised it. And the committed harness in `examples/` still runs software-attested against synthetic vectors, because genuine evidence embeds per-CPU identifiers and is not shippable as a fixture. See [attestation](attestation.md) and [hardware-validation](../hardware-validation.md). ### P-7 Sealed payload diff --git a/docs/spec/provenance-dag.md b/docs/spec/provenance-dag.md index 68c671e..b167d03 100644 --- a/docs/spec/provenance-dag.md +++ b/docs/spec/provenance-dag.md @@ -1,5 +1,7 @@ # Provenance DAG +Provenance is the record of who decided what, under which permission. This page explains the records cA2A leaves at each handoff, how they link back to the one before, and why only the signed form proves who produced them. It is for developers building or auditing those records. + A delegation credential describes authority. A provenance record describes a decision made under that authority. cA2A provides both unsigned `DelegationRecord` helpers and a signed TRACE binding. Choose the signed form when a recipient needs to authenticate who produced the evidence. ## DelegationRecord diff --git a/docs/spec/response-authentication.md b/docs/spec/response-authentication.md index 8ef4be7..9a29c36 100644 --- a/docs/spec/response-authentication.md +++ b/docs/spec/response-authentication.md @@ -1,5 +1,7 @@ # Live response authentication +When an agent sends a task and gets an answer back, it needs to know the answer came from the agent it checked and belongs to the request it sent. This page describes the opt-in setting that gives the live caller that assurance, and its limits. It is for developers using the reference client and server. + `ca2a-response-mac-v1` implements the live-caller branch of [the response requirements](response-binding-requirements.md), tracked in [#188](https://github.com/agentrust-io/ca2a/issues/188). This is an opt-in diff --git a/docs/spec/response-binding-requirements.md b/docs/spec/response-binding-requirements.md index 63c7f34..2f4f447 100644 --- a/docs/spec/response-binding-requirements.md +++ b/docs/spec/response-binding-requirements.md @@ -1,5 +1,7 @@ # Authenticated response requirements +This page sets out the requirements any method must meet to prove an answer came back from the checked agent and matches the request sent. It is the agreed basis for that work and is for implementers and reviewers; the [live response authentication](response-authentication.md) page describes what is built today. + Status: proposed requirements and acceptance matrix for [#188](https://github.com/agentrust-io/ca2a/issues/188). The [live response authentication profile](response-authentication.md) now implements a session-MAC verifier and reference adapter against this contract. diff --git a/docs/spec/sealed-channel.md b/docs/spec/sealed-channel.md index a52596e..20615b9 100644 --- a/docs/spec/sealed-channel.md +++ b/docs/spec/sealed-channel.md @@ -2,6 +2,8 @@ # Sealed Peer Channel +The sealed channel encrypts a task so that only the agent it is meant for can read it. This page explains the encryption used, lets you try it in a few lines of Python, and says what hardware it takes before the protection covers the machine's own administrators. It is for implementers and security reviewers. + The sealed channel encrypts a task to a peer's X25519 public key. Only the matching private key can open it. The reference runtime connects this encryption to channel-offer appraisal; software mode exercises the same encryption without proving hardware isolation. ## Scheme diff --git a/docs/spec/threat-model.md b/docs/spec/threat-model.md index e472689..8167887 100644 --- a/docs/spec/threat-model.md +++ b/docs/spec/threat-model.md @@ -1,5 +1,7 @@ # Threat Model +A threat model lists who might attack a system, what they could try, and what stops them. This page does that for agents handing work to each other, and says plainly which attacks are out of scope. It is for security reviewers and anyone deciding whether cA2A fits their risk. + cA2A defends the delegation path between agents. This page states the adversary, the assets, and what is and is not in scope. ## Adversary @@ -10,7 +12,7 @@ A capable adversary who may: - Present a valid A2A Signed Agent Card while running tampered or unmeasured code. - Sit on the network between two agents, or operate the host a peer runs on. - Attempt to widen a delegated grant, replay a credential into another chain, or reparent a provenance record. -- Obtain a copy of a delegation chain issued to somebody else — from an audit bundle, a log, a published provenance DAG, or the wire — and present it as its own, including while honestly attesting its own runtime. +- Obtain a copy of a delegation chain issued to somebody else (from an audit bundle, a log, a published provenance DAG, or the wire) and present it as its own, including while honestly attesting its own runtime. Out of adversary scope: breaking the underlying cryptographic primitives (Ed25519, the hash function), or compromising TEE firmware or hardware microcode. Those are the trust anchors. diff --git a/docs/spec/trace-a2a-profile.md b/docs/spec/trace-a2a-profile.md index 1d367ca..f59897c 100644 --- a/docs/spec/trace-a2a-profile.md +++ b/docs/spec/trace-a2a-profile.md @@ -1,5 +1,7 @@ # TRACE A2A Profile +TRACE is the AgenTrust format for signed records of what an AI system did. This page describes the small addition cA2A makes to TRACE so each handoff's record points to the one before it, letting anyone rebuild and check the full path of a task offline. + cA2A emits a TRACE record per delegation hop. The A2A profile adds a delegation-link block to the TRACE record so a chain of records forms a verifiable delegation DAG. ## The delegation-link block diff --git a/docs/spec/transport.md b/docs/spec/transport.md index 495ee8c..3785c13 100644 --- a/docs/spec/transport.md +++ b/docs/spec/transport.md @@ -1,5 +1,7 @@ # Transport Binding +This page explains how cA2A's extra fields travel inside ordinary A2A messages without changing A2A itself, and lists which parts of that are built today. It is for developers connecting cA2A to an A2A server or client. + cA2A is a profile on A2A, not a competing transport. A2A moves tasks and context between agents and authenticates a peer's domain with the Signed Agent Card. cA2A adds a trust envelope around a delegated task and leaves the wire protocol untouched. This page states how the profile attaches to the transport and what a peer does with the attached data. For the higher-level statement of what the profile adds and where, see [the A2A profile binding](profile.md). ## What ships today versus what does not diff --git a/docs/spec/verification-library.md b/docs/spec/verification-library.md index b6f8be7..4ad1626 100644 --- a/docs/spec/verification-library.md +++ b/docs/spec/verification-library.md @@ -1,5 +1,7 @@ # Verification Library +`ca2a-verify` is the library and command-line tool that checks permission chains and signed handoff records offline, with no network access. This page lists its functions and options. It is for developers and auditors who need to check evidence after the fact. + `ca2a-verify` checks delegation credentials and signed TRACE record paths offline. The caller supplies trusted credential issuers and record-signing keys; cryptographic consistency alone does not establish authorization. ## API diff --git a/docs/tutorials/authoring-a-delegation-credential.md b/docs/tutorials/authoring-a-delegation-credential.md index 9b49f4d..58954b6 100644 --- a/docs/tutorials/authoring-a-delegation-credential.md +++ b/docs/tutorials/authoring-a-delegation-credential.md @@ -1,6 +1,8 @@ # Authoring a Delegation Credential -The [verify-a-delegation-chain](verify-a-delegation-chain.md) tutorial takes an existing chain apart. This one builds one from scratch: generate keys, construct a `DelegationCredential`, sign it, extend it into a narrowing multi-hop chain, and verify the result. Then we make a child over-scope and watch `verify_chain` reject it with `SCOPE_ESCALATION`. No hardware needed. +This tutorial is for developers who want to issue permissions to agents in code. A delegation credential is a signed permission slip: one agent (the issuer) grants another (the subject) a list of permissions (the scope). You will create keys, write and sign a first slip, pass narrower slips down a chain of three agents, and check the result. Then you will make one agent try to grant more than it was given and watch `verify_chain` refuse it with `SCOPE_ESCALATION`. No special hardware is needed. + +The [verify a saved chain](verify-a-delegation-chain.md) tutorial picks up where this one ends. Everything here uses `ca2a_runtime.delegation`. For the field semantics and the full invariant table, see [the delegation chain spec](../spec/delegation-chain.md). @@ -12,7 +14,7 @@ The example credentials omit validity bounds to keep the field walkthrough short ## 1. Generate keypairs -Each hop is signed by its issuer and names a subject. Both are Ed25519 public keys, encoded as raw hex. `new_keypair()` returns the private key object and its public key hex. +Each agent needs a key pair: a private key it keeps secret and signs with, and a public key others use to check its signature. Each handoff (hop) is signed by its issuer and names a subject, and both are identified by their public keys (Ed25519 keys, written as hex). `new_keypair()` returns the private key object and its public key hex. ```python from ca2a_runtime.delegation import new_keypair @@ -62,7 +64,7 @@ else: ## 3. Extend the chain with narrowing scope -Each subsequent hop is issued by the previous hop's subject. Continuity is the rule that a hop's `issuer` equals the previous hop's `subject`, its `parent_id` equals the previous hop's `credential_id`, and its `depth` is the previous depth plus one. B, holding `read+write+admin`, delegates a narrower `read+write` slice to C: +Each later handoff is issued by the agent that received the one before it. Continuity is the rule that a hop's `issuer` equals the previous hop's `subject`, its `parent_id` equals the previous hop's `credential_id`, and its `depth` is the previous depth plus one. B, holding `read+write+admin`, delegates a narrower `read+write` slice to C: ```python mid = DelegationCredential( @@ -86,7 +88,7 @@ leaf = DelegationCredential( ).sign(c_priv) # signed by C ``` -Scope narrows at every hop: `{read, write, admin}` to `{read, write}` to `{read}`. Attenuation requires each hop's `scope` to be a subset of its parent's; it may stay the same or shrink, never grow. +Scope narrows at every hop: `{read, write, admin}` to `{read, write}` to `{read}`. This rule is called attenuation: each hop's `scope` must fit inside its parent's. It may stay the same or shrink, never grow. ## 4. Verify the chain @@ -138,7 +140,7 @@ else: raise AssertionError("scope escalation accepted") ``` -The signature on `over` is valid; C really did sign it. That is the point. A well-formed signature proves only that C authored the grant, not that C was entitled to make it. The subset check on `scope` is what forecloses the confused-deputy move where a delegate quietly widens its own authority. See [the delegation chain spec](../spec/delegation-chain.md#attenuation-is-the-whole-point). +The signature on `over` is valid; C really did sign it. That is the point. A valid signature proves only that C wrote the grant, not that C was entitled to make it. The scope check is what stops a delegate from quietly widening its own authority (security people call this the confused-deputy problem). See [the delegation chain spec](../spec/delegation-chain.md#attenuation-is-the-whole-point). ## 6. Serialize for the wire diff --git a/docs/tutorials/emit-and-verify-provenance.md b/docs/tutorials/emit-and-verify-provenance.md index 6a23c0c..be3181e 100644 --- a/docs/tutorials/emit-and-verify-provenance.md +++ b/docs/tutorials/emit-and-verify-provenance.md @@ -1,6 +1,6 @@ # Emit and Verify Provenance -Build an unsigned record path, detect a broken link, and see why consistent hashes alone do not authenticate evidence. First run the Python blocks in [authoring a delegation credential](authoring-a-delegation-credential.md), which install the package and define a verified `chain` and independently retained `trusted_roots`. Continue in the same script or session. +This tutorial is for developers who need a trail of records showing each handoff in a task. You build a chain of records where each one holds a fingerprint (hash) of the one before, catch a broken link, and then see why those fingerprints alone cannot prove who wrote the records, which is what the signed TRACE form is for. First run the Python blocks in [authoring a delegation credential](authoring-a-delegation-credential.md), which install the package and define a verified `chain` and independently retained `trusted_roots`. Continue in the same script or session. ## Emit one record per credential @@ -67,7 +67,7 @@ This does not change the signed delegation or grant additional runtime authority ## Use signed evidence for authenticity -The CLI now separates authenticated lineage from structural diagnostics: +Signed TRACE records fix the gap above: each record is signed by the agent that made it, so a rewrite is caught unless the attacker also holds that agent's key. The command-line tool reports a signed, checked path separately from a path that only looks consistent: ```bash ca2a verify-lineage --dag signed-trace-records.json --chain chain.json \ @@ -84,14 +84,15 @@ Revocation is reported separately; absent revocation evidence is `not_checked`. `--at-time` applies to credential validity and revocation; TRACE freshness uses the current clock, optionally bounded by `--max-age-seconds`. -Migration: `ca2a verify-dag` still reads the original unsigned format, but valid -structure now returns `verified: false`, `structural_verified: true`, -`code: UNAUTHENTICATED_LINEAGE` and exit 1. Add `--structural-only` to obtain exit -0 for a successful diagnostic; it never changes `verified` to true. Structural -failures still return exit 1. This is an intentional CLI compatibility change. -Existing native records cannot be upgraded by relabeling them: their producers -must emit and sign TRACE records. The native Python helpers retain their return -types and perform structural checks only. +??? info "Technical detail: migrating from the unsigned format" + Migration: `ca2a verify-dag` still reads the original unsigned format, but valid + structure now returns `verified: false`, `structural_verified: true`, + `code: UNAUTHENTICATED_LINEAGE` and exit 1. Add `--structural-only` to obtain exit + 0 for a successful diagnostic; it never changes `verified` to true. Structural + failures still return exit 1. This is an intentional CLI compatibility change. + Existing native records cannot be upgraded by relabeling them: their producers + must emit and sign TRACE records. The native Python helpers retain their return + types and perform structural checks only. This authenticates the submitted path's declarations, not the truth of every declaration. It does not establish task completion, a unique or complete history, diff --git a/docs/tutorials/integrating-with-a2a.md b/docs/tutorials/integrating-with-a2a.md index 0c9632e..86f85a4 100644 --- a/docs/tutorials/integrating-with-a2a.md +++ b/docs/tutorials/integrating-with-a2a.md @@ -1,6 +1,12 @@ # Integrating with A2A -This example connects the official Python A2A SDK's client and HTTP server to +This guide is for developers who already run an A2A agent and want to add cA2A +checks to it. You run a small example where an ordinary A2A server and client, +built with the official Python A2A software development kit (SDK), talk over a +real local connection, and cA2A checks each protected request before the +application acts on it. + +In technical terms, this example connects the official Python A2A SDK's client and HTTP server to cA2A's existing Agent Card and peer-verification APIs. It exercises an actual loopback connection with `a2a-sdk==1.1.2`. The operator owns the card, server, application routing, and tool handler; cA2A supplies the extension metadata and diff --git a/docs/tutorials/reproducing-the-claims.md b/docs/tutorials/reproducing-the-claims.md index 5f38e64..81e5df9 100644 --- a/docs/tutorials/reproducing-the-claims.md +++ b/docs/tutorials/reproducing-the-claims.md @@ -1,6 +1,6 @@ # Reproducing the Claims -Run six software experiments from the source checkout. They exercise delegation, policy intersection, encrypted payloads, hash links, and synthetic attestation. None requires a TEE. Their results establish the specific cases below, not hardware protection or complete profile conformance. +This page is for anyone who wants to check cA2A's six claims for themselves instead of taking them on trust. Each claim has a small script you run from the source code: permissions that can only narrow, refusing a grant copied from another chain, combining a grant with local rules, encrypting a task, linked records, and hardware-style checks using made-up reports. None needs a TEE (a trusted execution environment, the protected hardware area used for confidential computing). The results prove the specific cases below, not hardware protection or full conformance to the specification. ## Install and run diff --git a/docs/tutorials/verify-a-delegation-chain.md b/docs/tutorials/verify-a-delegation-chain.md index ee811f9..b56dd9f 100644 --- a/docs/tutorials/verify-a-delegation-chain.md +++ b/docs/tutorials/verify-a-delegation-chain.md @@ -1,6 +1,6 @@ # Verify a Saved Delegation Chain -Save a locally generated chain, verify it using a separately retained root key, then detect an edited signature. This walkthrough builds on [authoring a delegation credential](authoring-a-delegation-credential.md): install that checkout and run its Python blocks first, in the same session. They define `chain`, `a_pub`, and `trusted_roots`, and already test a correctly signed scope escalation. +This tutorial shows how to save a permission chain to a file and check it later, as an auditor or a receiving agent would. You save the chain, check it against the root key you kept separately (the starting authority you trust), then change one signed field and watch the check fail. This walkthrough builds on [authoring a delegation credential](authoring-a-delegation-credential.md): install that checkout and run its Python blocks first, in the same session. They define `chain`, `a_pub`, and `trusted_roots`, and already test a correctly signed scope escalation. ## Save and verify diff --git a/index.md b/index.md index b702ee6..6211ce8 100644 --- a/index.md +++ b/index.md @@ -10,13 +10,13 @@ description: cA2A adds delegation and peer trust checks to A2A. Start with an of # Verify who delegated what to each agent -cA2A is a profile on A2A that adds signed attenuated delegation, peer appraisal, a sealed peer channel and a TRACE provenance record per hop, checkable offline against a root you trust. +When one AI agent hands work to another, cA2A records who gave which permission to whom, and lets anyone check that no agent quietly gave itself more. It sits on top of A2A, the common protocol agents use to talk to each other (see [the terms, in plain English](https://agentrust-io.com/#plain-terms)). Each handoff carries a signed permission slip that can only shrink, each agent can be asked for hardware proof of what it is running, the task can be encrypted so only the checked agent can read it, and each step leaves a signed record you can check offline against a starting authority you chose to trust. [Verify your first delegation chain](docs/quickstart.md){ .md-button .md-button--primary } [What this proves, and what it does not](LIMITATIONS.md){ .md-button } !!! tip "TL;DR" - [ca2a-runtime](https://pypi.org/project/ca2a-runtime/) 0.4.0 (MIT developer preview; the PyPI name `ca2a` belongs to an unrelated project) rejects scope escalation offline with no hardware or running peer. SEV-SNP and TDX appraisal ran on real Azure and GCP evidence, including an Azure SEV-SNP peer calling a GCP TDX peer on 2026-07-27, but peer appraisal is one-directional so far and binding the seal to a verified measurement on a live call is on the roadmap. + [ca2a-runtime](https://pypi.org/project/ca2a-runtime/) 0.4.0 (MIT developer preview; the PyPI name `ca2a` belongs to an unrelated project) catches an agent that tries to pass on more permission than it was given, offline, with no special hardware and no running agents. Checks of AMD SEV-SNP and Intel TDX hardware reports ran on real Azure and GCP machines, including an Azure agent calling a GCP agent on 2026-07-27, but across clouds the check has only run in one direction so far, and tying the encrypted task to a checked hardware measurement on a live call is on the roadmap.
@@ -24,7 +24,7 @@ cA2A is a profile on A2A that adds signed attenuated delegation, peer appraisal, --- - Verify a narrowed grant and reject both an untrusted issuer and signed scope escalation, then stand up the live peer runtime. + Check a two-step handoff where the permission narrows, then watch it refuse a starting authority you never trusted and a correctly signed grant that asks for too much. No hardware needed. [Quick Start](docs/quickstart.md) @@ -32,7 +32,7 @@ cA2A is a profile on A2A that adds signed attenuated delegation, peer appraisal, --- - What has run against real silicon, what is one-directional, and what is not appraised at all. + What has been checked on real hardware, what has only been checked in one direction, and what is not checked at all. [Limitations](LIMITATIONS.md) @@ -40,7 +40,7 @@ cA2A is a profile on A2A that adds signed attenuated delegation, peer appraisal, --- - SEV-SNP on Azure and Intel TDX on GCP C3, validated 2026-07-27, with the collectors run on real silicon on 2026-08-24. + Real AMD SEV-SNP reports from Azure and Intel TDX reports from GCP C3 machines, checked on 2026-07-27. The code that requests those reports ran on real chips on 2026-08-24. [Hardware validation](docs/hardware-validation.md) @@ -48,7 +48,7 @@ cA2A is a profile on A2A that adds signed attenuated delegation, peer appraisal, --- - Before it: [Agent Manifest](https://manifest.agentrust-io.com) issues the attenuated delegation credential. Alongside: [cMCP](https://cmcp.agentrust-io.com) covers tool calls. Each hop's record is written in [TRACE](https://trace.agentrust-io.com). Check a real TDX quote at [agentrust-io.com/verify](https://agentrust-io.com/verify/). + Before it: [Agent Manifest](https://manifest.agentrust-io.com) describes the agent and issues the narrowed permission. Alongside: [cMCP](https://cmcp.agentrust-io.com) covers an agent's tool calls. Each handoff's record is written in [TRACE](https://trace.agentrust-io.com). Check a real Intel TDX hardware report yourself at [agentrust-io.com/verify](https://agentrust-io.com/verify/). [See the chain](https://agentrust-io.com/#chain) @@ -56,19 +56,19 @@ cA2A is a profile on A2A that adds signed attenuated delegation, peer appraisal, ## The gap it closes -An agent identity does not by itself establish delegation authority. When A delegates to B and B delegates to C, the relying party needs to authenticate the root and check each grant. Live calls also need caller authentication, local policy, and any required runtime appraisal. +Knowing an agent's name does not tell you what it is allowed to do. When agent A hands a task to B, and B hands part of it to C, the agent receiving the work (the relying party) needs to confirm where the permission started and check every handoff along the way. On a live call it also needs to confirm the caller is who the permission names, apply its own rules, and, if it asks for one, check hardware proof of what the caller is running. ## The four primitives -| Mechanism | What to check | Start here | -|---|---|---| -| Delegation credentials | Trusted root, signatures, continuity, bounded scope and depth | [Offline quickstart](docs/quickstart.md) | -| Runtime appraisal | Evidence and measurements required by the relying party | [Attestation](docs/spec/attestation.md) | -| Sealed peer channel | Payload encryption to the appraised peer key | [Sealed channel](docs/spec/sealed-channel.md) | -| Linked provenance | Record signatures and parent links | [TRACE A2A profile](docs/spec/trace-a2a-profile.md) | +| Mechanism | In plain terms | What to check | Start here | +|---|---|---|---| +| Delegation credentials | A signed permission slip per handoff that can only narrow | Trusted root, signatures, continuity, bounded scope and depth | [Offline quickstart](docs/quickstart.md) | +| Runtime appraisal | Hardware proof of what the other agent is running | Evidence and measurements required by the relying party | [Attestation](docs/spec/attestation.md) | +| Sealed peer channel | The task encrypted so only the checked agent can read it | Payload encryption to the appraised peer key | [Sealed channel](docs/spec/sealed-channel.md) | +| Linked provenance | A signed record per handoff, each pointing at the one before | Record signatures and parent links | [TRACE A2A profile](docs/spec/trace-a2a-profile.md) | -Software and hardware modes provide different assurance. Peer appraisal has been demonstrated one-directionally; mutual simultaneous hardware attestation remains outstanding. Read [Limitations](LIMITATIONS.md) before relying on a hardware claim. +Running without special hardware (software mode) gives weaker guarantees than running on confidential-computing hardware. Hardware checks have run in one direction across two clouds, and in both directions between two machines run by one operator on 2026-09-17; both agents proving themselves to each other at the same moment is still open. Read [Limitations](LIMITATIONS.md) before relying on a hardware claim. -For the architecture and trust boundaries, read [How It Works](docs/concepts.md). The normative profile, with the delegation chain, sealed channel, and conformance rules, is in [Profile](docs/spec/profile.md). +For how the pieces fit together, read [How It Works](docs/concepts.md). The formal rules, with the delegation chain, sealed channel, and conformance requirements, are in [Profile](docs/spec/profile.md). **Status:** ca2a-runtime 0.4.0 developer preview · MIT · hosting at the Agentic AI Foundation proposed, not accepted · Sponsored by OPAQUE, which funds the engineering, infrastructure and confidential-computing work behind these projects.