Skip to content

Configuration

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 (one running cA2A agent) and serve it over the reference HTTP transport.

Reference

attestation:
  provider: auto            # auto | tpm | sev-snp | tdx | 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

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. Any other value is rejected as an unknown provider.
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.