Summary
The key document published at /.well-known/agent-keys.json carries no
signature. Its authenticity rests entirely on the TLS connection that served
it, which makes write access to the web server equivalent to possession of the
trust root's signing key. Section 8 does not treat the publication channel as
its own threat, and none of §8.2's mitigations apply to it.
What the document is today
KeyDocument (agent-uri-attestation/src/key_document.rs:111) has three
fields and no fourth:
pub struct KeyDocument {
trust_root: String,
keys: Vec<PublishedKey>,
#[serde(default)]
revoked_keys: Vec<RevokedKey>,
}
That matches §7.2's response format, so this is a specification property rather
than an implementation gap.
Why this is not covered by §8.2
§8.2 covers a compromised signing key thoroughly: revocation on both
granularities, overlap windows, short exp, HSMs. Compromising the
publication host reaches the same outcome — minting attestations that verify
for the whole namespace — but every mitigation §8.2 offers is unavailable:
| §8.2 mitigation |
Against a compromised publication host |
revoked_keys list |
The attacker serves the document that carries the list |
| Key rotation with overlap |
The attacker publishes the incoming key |
| HSM protection |
The signing key was never the target |
Short exp |
Bounds each token, not the attacker's ability to mint more |
Revocation is the load-bearing one, and it inverts here: the channel a verifier
consults to learn that a key is bad is the channel the attacker controls.
§8.3 is the nearest coverage, but it addresses a different threat — an
attacker claiming a domain they do not control — and its mitigation ("DNS and
TLS provide domain authentication") is exactly what a host compromise defeats,
because the attacker is serving from the legitimate domain with a legitimate
certificate.
Why the client cannot close it
agent-uri-attestation-wellknown already enforces every check §7.2 asks for:
HTTPS-only, no redirects, caps on declared and actual body length, and the
requirement that a document name the root that served it. Each of those
defends the channel. None of them can distinguish a document the trust root
authored from one an attacker wrote to the same path, because there is nothing
in the document to distinguish them by.
This is also not something a hardened server deployment fixes. A compromised
application server is exactly as fatal as a compromised nginx.
Proposed mitigation
Sign the key document with an offline root key, so the web host never holds
signing material:
- Add a signature field to §7.2's response format covering the document body.
- The signing key stays offline; publication becomes a file copy.
- Verifiers pin the root key out of band, as a deployment decision — §7.2
already establishes that "which trust roots matter is a deployment decision".
Host compromise then degrades to denial of service and stale-document
replay, rather than namespace takeover.
Open questions
- Bootstrap. A self-signed document is circular: whoever writes the file
writes the signature. The root key has to be pinned out of band for this to
buy anything, which is real deployment cost and worth weighing against the
threat.
- Replay of a stale signed document. Signing alone does not stop an
attacker serving an older validly-signed document that predates a
revocation. Needs a monotonic version or freshness bound, which is
additional mechanism.
- Whether the cost is worth it. For a deployment where the trust root
already runs its own infrastructure, the added key-management burden may
exceed the risk. The alternative is to leave the design as it is and state
the limitation explicitly in §8 so operators can decide.
At minimum, §8 should name this threat and its residual risk, even if the
signed-document mitigation is not adopted.
Scope
Specification change (§7.2 response format, new §8 subsection). Implementation
in agent-uri-attestation and agent-uri-attestation-wellknown follows from
whatever the specification settles on.
Summary
The key document published at
/.well-known/agent-keys.jsoncarries nosignature. Its authenticity rests entirely on the TLS connection that served
it, which makes write access to the web server equivalent to possession of the
trust root's signing key. Section 8 does not treat the publication channel as
its own threat, and none of §8.2's mitigations apply to it.
What the document is today
KeyDocument(agent-uri-attestation/src/key_document.rs:111) has threefields and no fourth:
That matches §7.2's response format, so this is a specification property rather
than an implementation gap.
Why this is not covered by §8.2
§8.2 covers a compromised signing key thoroughly: revocation on both
granularities, overlap windows, short
exp, HSMs. Compromising thepublication host reaches the same outcome — minting attestations that verify
for the whole namespace — but every mitigation §8.2 offers is unavailable:
revoked_keyslistexpRevocation is the load-bearing one, and it inverts here: the channel a verifier
consults to learn that a key is bad is the channel the attacker controls.
§8.3 is the nearest coverage, but it addresses a different threat — an
attacker claiming a domain they do not control — and its mitigation ("DNS and
TLS provide domain authentication") is exactly what a host compromise defeats,
because the attacker is serving from the legitimate domain with a legitimate
certificate.
Why the client cannot close it
agent-uri-attestation-wellknownalready enforces every check §7.2 asks for:HTTPS-only, no redirects, caps on declared and actual body length, and the
requirement that a document name the root that served it. Each of those
defends the channel. None of them can distinguish a document the trust root
authored from one an attacker wrote to the same path, because there is nothing
in the document to distinguish them by.
This is also not something a hardened server deployment fixes. A compromised
application server is exactly as fatal as a compromised nginx.
Proposed mitigation
Sign the key document with an offline root key, so the web host never holds
signing material:
already establishes that "which trust roots matter is a deployment decision".
Host compromise then degrades to denial of service and stale-document
replay, rather than namespace takeover.
Open questions
writes the signature. The root key has to be pinned out of band for this to
buy anything, which is real deployment cost and worth weighing against the
threat.
attacker serving an older validly-signed document that predates a
revocation. Needs a monotonic version or freshness bound, which is
additional mechanism.
already runs its own infrastructure, the added key-management burden may
exceed the risk. The alternative is to leave the design as it is and state
the limitation explicitly in §8 so operators can decide.
At minimum, §8 should name this threat and its residual risk, even if the
signed-document mitigation is not adopted.
Scope
Specification change (§7.2 response format, new §8 subsection). Implementation
in
agent-uri-attestationandagent-uri-attestation-wellknownfollows fromwhatever the specification settles on.