SW-A2A-004: Agent endpoint or authentication URL not served over HTTPS
Last updated 7 November 2026
| Fact | Value |
|---|---|
| Severity | High |
| Checks | A2A agent card |
| Malicious indicator | No |
| OWASP Agentic Top 10 | ASI07 |
| OWASP MCP Top 10 | None mapped |
| NIST SP 800-53 | SC-8 (provisional mapping to SP 800-53 base controls) |
| First shipped in | Scanner 1.3.0 |
What it detects
The rule reads every address the card uses to reach the agent or to authenticate: the url of each entry of supportedInterfaces (for an older card, the url and additionalInterfaces), the oauth2MetadataUrl and openIdConnectUrl of a security scheme, the authorizationUrl, tokenUrl, refreshUrl and deviceAuthorizationUrl of an OAuth flow, and the jku of a signature. An address that starts with http:// and whose host is not loopback is a finding that shows the address without its user name, query and fragment. Loopback means localhost, any 127.x.x.x address and ::1, so a card for local development is left alone.
An interface url with a scheme other than http, https or grpcs is a finding too, with the reason scheme. A GRPC interface written as host:port cannot be judged from its text and is not reported. A remote agent listed in a2a.agents with a plain http:// address is never fetched; it is reported when its host is public by its text, and an address such as 10.0.0.5, localhost or billing.internal gets no finding.
Why it matters
Plain HTTP carries every request and every answer in the clear, and anyone on the path can read or change them. For an agent endpoint that means the task a client sends and the result it gets back. For an OAuth or OpenID Connect address it means the sign-in itself, including the codes and tokens that follow. A changed token endpoint or key set can hand a client to someone else's server. The scanner maps this rule to OWASP ASI07, Insecure Inter-Agent Communication, and to NIST SP 800-53 control SC-8, Transmission Confidentiality and Integrity.
Example
A complete card whose only fault is its endpoint, written with http:// on a host that does not exist (example.invalid):
.well-known/agent-card.json
{
"name": "demo-agent",
"description": "Drafts release notes from merged pull requests.",
"version": "1.0.0",
"supportedInterfaces": [
{
"url": "http://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 points at /supportedInterfaces/0/url and shows the address. Use your own host and an https:// address in a real card.
How to fix
Serve the endpoint and every authentication address over https:// and change the card to say so. Get a certificate for the host, and let the card name the final address, not one that redirects. For a card that is only for local development, use localhost or 127.0.0.1 so the scanner leaves it alone, and do not publish it.
If it is a false positive
An http:// address on an internal name that resolves only inside your network is still reported, because the rule judges the text of the address and exempts only loopback. If the traffic never leaves a trusted network and the card is not published, accept the finding with a note that says so. A card that is public should not need the note.
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.