cardcheck
One line: should my agent trust this A2A peer agent's card?
In the A2A (Agent2Agent) protocol, an agent advertises itself with a
public card at /.well-known/agent-card.json. A malicious card can
impersonate another organization, or carry injection in the fields
your agent will read as trusted description text. cardcheck fetches
the card (or reads a local one) and runs five keyless checks:
- identity: does the host it was served from match the origin the card claims to speak for? A different registrable domain is a HIGH impersonation signal.
- injection:
warden's engine over every text field (name, description, skills). - confusables: a homoglyph / mixed-script check on the agent and provider names.
- capability over-reach and provider trust (informational).
The signature honesty note
cardcheck reports whether a JWS signature is present and
well-formed only. It does not cryptographically verify signatures,
and its output never claims a signature is valid or verified; the
result type has no "verified" state, and a test asserts the output
never says so. Full JWS verification is a tracked future addition.
Treat signature present as "the publisher bothered to sign", not
"the signature checks out".
Usage
vulkro-live cardcheck example.com
vulkro-live cardcheck https://agents.example.com/.well-known/agent-card.json
vulkro-live cardcheck --file ./agent-card.json # nothing leaves the machine
cat card.json | vulkro-live cardcheck --file -
Only public metadata leaves your machine (the card fetch itself); with
--file or stdin nothing leaves at all.
Example
A card whose skill description carries injected instructions:
$ vulkro-live cardcheck --file ./agent-card.json
AVOID (local card)
identity declared 'acme-support-agent' for https://agents.acme-corp.example/a2a
signature absent
provider Acme Corp
findings:
HIGH skills[0].description the text contains an instruction-injection phrase: "ignore previous"
HIGH skills[0].description the text contains an instruction-injection phrase: "do not mention"
LOW unsigned card is unsigned: it cannot be cryptographically bound to its domain
Flags
| Flag | Effect |
|---|---|
[TARGET] | The agent to fetch: a host (example.com), an https URL, or a full well-known card URL. Omit when reading a local card |
--file <FILE> | Read the card from a local JSON file instead of fetching. Use - for stdin |
--no-cache | Bypass the local response cache and always fetch live |
Exit codes: 0 for GREEN, 1 for REVIEW or AVOID, 2 on an error.
cardcheck prints its verdict report as text; it is not one of the
--format commands (see Output formats).