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 and serve it over the reference HTTP transport.
Reference¶
attestation:
provider: auto # auto | tpm | sev-snp | tdx | opaque | software-only
enforcement_mode: enforcing # enforcing | advisory | silent
require_caller_attestation: none # none | any | hardware
# caller_verifier: # required for `hardware`, optional for `any`
# platform: tpm # tpm today; sev-snp and tdx are refused (see below)
# trusted_roots_path: vtpm-roots.pem
challenge_ttl_seconds: 60
max_delegation_depth: 8 # reject chains deeper than this
listen_addr: "127.0.0.1:8443"
trusted_root_issuers:
- "<root Ed25519 public key as raw hex>"
local_policy: ["read", "write"] # allow-set for scope intersection (or use Cedar below)
# policy_bundle_path: policy.cedar
# Optional: verify and bind this peer's Agent Manifest identity at startup.
# agent_manifest:
# path: manifest.cose # v0.2 COSE envelope, or signed v0.1 JSON
# trust_anchor_path: manifest-key.json
# authenticated_subject: spiffe://example.test/agent/ca2a
Fields¶
| 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. |
attestation.enforcement_mode | enforcing | Intended mode. The peer path always fails closed on cA2A denials today; advisory and silent are accepted in config but not applied on the wire. |
attestation.require_caller_attestation | none | What the callee demands of a caller's own attestation, per mutual-attestation.md. none records the outcome and demands nothing; any requires an offer that appraises, software assurance included; hardware requires hardware assurance. At every rung an offer that is present and does not appraise is refused. |
attestation.caller_verifier | none | How to appraise a hardware report a caller offers. platform plus trusted_roots_path (a PEM bundle, resolved relative to the config file). Required when the rung is hardware; without it, a hardware offer at none or any is refused as unappraisable rather than accepted. Only tpm can be built today, via ca2a_verify.tpm.tpm_verifier. sev-snp and tdx are accepted by the vocabulary and refused at startup with the reason: their verifiers take raw evidence and a certificate chain, and no report-level wrapper exists yet. |
attestation.challenge_ttl_seconds | 60 | Lifetime of the challenge the callee issues for a caller to bind its offer into. The secret behind it is per-process and never persisted. |
max_delegation_depth | 8 | Chains deeper than this are rejected with DELEGATION_DEPTH_EXCEEDED. |
listen_addr | 127.0.0.1:8443 | Address ca2a start binds. The host is never defaulted, so serving on every interface has to be written out. |
trusted_root_issuers | none | Ed25519 public keys allowed to originate delegation chains. At least one is required by ca2a start; an internally valid chain from any other root is denied before policy evaluation. |
local_policy | none | Capability allow set for LocalPolicy. Required for ca2a start unless policy_bundle_path is set. |
policy_bundle_path | none | Path to a Cedar policy file, resolved relative to the config file. When set, used instead of local_policy. |
agent_manifest.path | none | Optional signed Agent Manifest. Content is sniffed: v0.1 JSON and v0.2 COSE are accepted; a bare v0.2 JSON payload is rejected because its COSE envelope is the signature. |
agent_manifest.trust_anchor_path | none | JSON trust anchor containing one public_key_base64url or a keys array. Relative paths resolve against the config file. |
agent_manifest.authenticated_subject | none | SPIFFE URI independently configured for this peer. Startup fails unless it equals the verified manifest's agent_id. All three agent_manifest fields must be configured together. |
There is no key field: a PeerNode generates its own X25519 channel keypair at startup and publishes the public half through the attestation handshake, so a caller seals to a key the node attested rather than one written into a file.
Validate and start¶
ca2a validate-config --config examples/minimal/ca2a-config.yaml
# ok: provider=software-only enforcement=enforcing
ca2a start --config examples/minimal/ca2a-config.yaml
# note: software-only provider, callers appraise this channel key as
# assurance="none" and the seal carries no hardware guarantee
# note: require_caller_attestation=none with no caller_verifier; software offers
# appraise, hardware offers are refused as unappraisable
# ca2a listening on 127.0.0.1:8443 (provider=software-only, require_caller_attestation=none)
require_holder_proof is not a config field. It is on for every node ca2a start builds; a program with a reason to turn it off constructs the PeerNode itself.
ca2a start needs no extra install: the reference transport is standard library only. It is one way to run the peer path, not part of the profile. A program that already has a Policy and a provider can build a PeerNode and serve it from its own A2A server instead.
Invalid values fail fast with a CONFIG_ERROR and a message naming the offending field.
When agent_manifest is configured, startup verifies the signature, supported version, expiry and revocation state before constructing the node. The verified identity is available as PeerNode.agent_manifest. cA2A does not claim runtime policy or tool-catalog artifact matching here: unlike cMCP it has no tool catalog, and its policy may be an inline allow set rather than a hash-addressed bundle.