How grading works
Every check result is deterministic: given the same directory and response headers, the checker always produces the same verdict and grade. This page is the auditable scoring reference.
3-state verdict
The verdict is shown at the top of every report. It has exactly three possible values.
| Verdict | What triggers it |
|---|---|
| VALID |
The directory exists, all keys are structurally valid
(kty, crv, and a 32-byte x),
and no private key material (d) is present. A custom
kid label is fine; the verdict does not depend on it.
|
| INVALID |
A directory was found at the well-known path, but at least one
critical check failed: private d present, wrong
kty or crv, x not 32 bytes,
or the Ed25519 signature does not verify. A custom kid
that differs from the thumbprint does not make a directory invalid.
|
| NOT FOUND | No usable directory at the well-known path: non-2xx HTTP response, response body is not JSON, the key set is empty, or the host is unreachable (including DNS failure). |
Letter grade
The letter grade (A through F) is only shown when a directory exists, that is when the verdict is VALID or INVALID. There is no letter grade for NOT FOUND.
The grade is derived from a weighted score that starts at 100 and subtracts points for each failed or warned check.
Scoring weights
Checks are grouped into three tiers. The deductions differ by tier and by severity (fail vs. warn).
| Tier | Fail deduction | Warn deduction |
|---|---|---|
| JWKS directory | -25 per fail | -6 per warn |
| RFC 9421 signature | -30 per fail | -8 per warn |
| Agent Card (advisory) | -6 per fail | -2 per warn |
Letter thresholds
| Letter | Minimum score |
|---|---|
| A | 90 or above |
| B | 75 to 89 |
| C | 60 to 74 |
| D | 40 to 59 |
| F | below 40, or capped (see below) |
Grade capping rules
Certain critical failures impose a hard ceiling on the grade regardless of the raw score.
| Condition | Effect |
|---|---|
| Private key material present in the directory | Grade is capped to F |
| Ed25519 signature fails to verify | Grade is capped to a maximum of D |
| Directory not served over HTTPS | Grade is capped low (treated as a critical failure) |
When a cap applies, the report notes the cap reason next to the grade so the cause is always visible.
Agent Card checks are advisory
Checks in the Agent Card tier nudge the score and can raise warnings, but they never change the verdict and never trigger a grade cap. A missing or incomplete Agent Card will lower the score slightly; it will not cause a VALID directory to become INVALID.
What is checked
JWKS directory checks
- Directory is served over HTTPS
- Directory URL returns HTTP 200
-
Response media type. The web-bot-auth type
(
application/http-message-signatures-directory+json) passes. Another valid JWKS type such asapplication/jwk-set+jsonor a genericapplication/jsonis accepted but raises a warning, because web-bot-auth asks for its own media type. A non-JSON type such astext/html, or a missing media type, is a failure. - Response body is valid JSON
- Key set has the expected shape (
keysarray) - Key set is non-empty
- Key set size is within reasonable bounds
- Caching headers are present
- Per-key:
kty=OKP - Per-key:
crv=Ed25519 - Per-key:
xis 32 bytes (base64url-encoded) -
Per-key: the RFC 7638 thumbprint is computed and shown. This is the
value a verifier matches an incoming signature's
keyidagainst. The JWKkidmember itself is a free-form label, so a customkidis allowed and only the signature'skeyidhas to be a thumbprint. This check is informational and never lowers the grade. - Per-key: no private key material (
dnot present) - No duplicate
kidvalues in the set - Validity window (if present) is plausible
RFC 9421 signature checks
Signature-Agentheader presentSignature-Inputparses correctly- Covered components include required fields
- Required signature parameters present
tag=web-bot-authcreatedandexpireswithin allowed clock skewkeyidresolves to a key in the directory- Ed25519 signature verifies against the resolved key
Agent Card checks (advisory)
client_namepresentclient_uripresentcontactspresentjwks_uripresentpurposepresent- RFC 9309 robots.txt compliance declaration
- Rate expectation declared