SW-A2A-012: Agent card is not signed
Last updated 7 November 2026
| Fact | Value |
|---|---|
| Severity | Low |
| Checks | A2A agent card |
| Malicious indicator | No |
| OWASP Agentic Top 10 | ASI07 |
| OWASP MCP Top 10 | None mapped |
| NIST SP 800-53 | SI-7 (provisional mapping to SP 800-53 base controls) |
| First shipped in | Scanner 1.3.0 |
What it detects
The rule fires on any card that has the card shape, in any format, when its signatures member is missing or is not a list with at least one entry. It reports the card once, with the reason unsigned, and says nothing about the card's content. It does not look at keys or algorithms; those belong to SW-A2A-010, 011, 013 and 017. A card with an entry that cannot be read is not unsigned, and SW-A2A-011 reports the entry instead.
Why it matters
A signed card lets a client check that the card it fetched is the one the owner published. An unsigned card can be changed by anyone who can change the file or the response: a compromised web server, a cache, or a proxy between the client and the agent. The A2A definition does not require a signature, which is why this finding is low, but it matters most for a card that other organisations fetch and rely on. The scanner maps this rule to OWASP ASI07, Insecure Inter-Agent Communication, and to NIST SP 800-53 control SI-7, Software, Firmware, and Information Integrity.
Example
A complete card with no signatures member:
.well-known/agent-card.json
{
"name": "demo-agent",
"description": "Drafts release notes from merged pull requests.",
"version": "1.0.0",
"supportedInterfaces": [
{
"url": "https://agent.example.invalid/a2a",
"protocolBinding": "JSONRPC",
"protocolVersion": "1.0"
}
],
"capabilities": {},
"securitySchemes": {
"bearer": {
"httpAuthSecurityScheme": {
"scheme": "Bearer"
}
}
},
"securityRequirements": [
{
"schemes": {
"bearer": {
"list": []
}
}
}
],
"defaultInputModes": [
"text/plain"
],
"defaultOutputModes": [
"text/plain"
],
"skills": [
{
"id": "release-notes",
"name": "Release notes",
"description": "Drafts release notes for one tag.",
"tags": [
"release"
]
}
]
}The finding is placed at the top of the file and says the card carries no signature.
How to fix
Sign the card as the last step of a release, with a key whose public half you list in the file that a2a.keys names, and put the result in the card's signatures member. The a2a-sdk package has a signer for this (a2a.utils.signing.create_agent_card_signer). From then on SW-A2A-010 and SW-A2A-013 check the key and the signature on every scan.
If it is a false positive
A card for a private agent that only your own clients read, or one that the server signs when it serves it, has nothing to sign in the repository. Accept the finding with a note that says where the signature is added, or that the card is not published.
If the finding is not a problem in your case, accept it with a note: in the dashboard a manager or owner can accept a finding and the note is kept with it; with the scanner on its own, add it to the baseline file with a reason and an expiry date.