SW-A2A-008: API key sent in the URL query
Last updated 7 November 2026
| Fact | Value |
|---|---|
| Severity | Medium |
| Checks | A2A agent card |
| Malicious indicator | No |
| OWASP Agentic Top 10 | ASI03 |
| OWASP MCP Top 10 | None mapped |
| NIST SP 800-53 | IA-5 (provisional mapping to SP 800-53 base controls) |
| First shipped in | Scanner 1.3.0 |
What it detects
The rule goes through the card's security schemes and looks at each API key scheme: the apiKeySecurityScheme of a 1.0 card, or a scheme of type apiKey in the 0.x shape. It reads the member that says where the key is sent, location in 1.0 and in in the 0.x shape, and reports the scheme when the value is query. A key sent in a header or a cookie is not reported. The finding points at that member of the scheme and never shows a key, because the card does not hold one.
Why it matters
An address is not handled as a secret. Web servers, proxies, load balancers and monitoring tools write the full request line to their logs, browsers keep it in their history, and the address is copied into the Referer header, tickets and chat messages. A key sent in the query ends up in places that were never meant to protect it, and those copies outlive the request. The scanner maps this rule to OWASP ASI03, Identity and Privilege Abuse, and to NIST SP 800-53 control IA-5, Authenticator Management.
Example
A complete card with an API key scheme whose location is the query string:
.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": {
"key": {
"apiKeySecurityScheme": {
"location": "query",
"name": "api_key"
}
}
},
"securityRequirements": [
{
"schemes": {
"key": {
"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 points at the location member of the scheme and shows the value query.
How to fix
Send the key in a header, either Authorization or one of your own. Set the scheme's location to header and put the header's name in name. Change the agent to read the key from there, rotate every key that has already travelled in an address, and search your logs for it.
If it is a false positive
A key that is not a secret, such as a public identifier used to count calls to an endpoint that holds no private data, is harmless in an address. Accept the finding with a note that says the key identifies a caller and does not authorise anything. If anyone could do more than read public data with the key, treat the finding as real.
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.