Overview
Every verification verdict is signed with an ES256 JWT attestation — a cryptographic proof that the verification took place. This enables:- Tamper detection — any modification invalidates the signature
- Non-repudiation — the signing service is identified by DID
- Audit compliance — attestations are stored and queryable
- Cross-service verification — any QWED node can verify the token
How it works
JWT structure
Header
kid is derived from a SHA-256 fingerprint of the public key, so it stays stable as long as QWED_A2A_SIGNING_KEY_PEM is unchanged — even across process restarts.
Payload
Configure the signing key
QWED A2A requires a persistent ECDSA P-256 signing key so that JWT attestations signed before a restart can still be verified afterwards. Keys are never generated inside the process — the service loads them from theQWED_A2A_SIGNING_KEY_PEM environment variable (or the pem_key constructor argument).
Generate an unencrypted PKCS#8 P-256 key with openssl:
key_id and can verify each other’s tokens.
Signing a verdict
Verifying an attestation
Verification outcomes
Tamper detection
Thesub claim contains a SHA-256 hash of the original payload:
Publishing the public key (JWKS)
External consumers verify attestations by fetching the public key.A2ACryptoService.get_public_key_jwk() returns the current key in JWK format:
GET /.well-known/jwks.json so downstream services and auditors can fetch keys over HTTP.
Cross-service verification
Because every replica loads the same PEM fromQWED_A2A_SIGNING_KEY_PEM, they all derive the same key_id and can verify each other’s tokens:
Fail-closed behavior
QWED A2A treats missing or invalid signing keys as an unrecoverable configuration error, not a soft warning. There is no ephemeral-key fallback.
The FastAPI gateway surfaces these as
HTTP 503 Signing key unavailable on both /a2a/intercept and /.well-known/jwks.json so orchestrators can detect a misconfigured deployment before it accepts traffic.