ADR-015: Raw Ed25519 Signature Format
Status: Accepted Date: 2026-03-25 Relates to: ADR-007 (Security and Anti-Gaming)
Context
The protocol requires the trust authority to sign every successful response. ADR-007 specified Ed25519 as the signing algorithm but described the signature format as "JWS Compact Serialization." This left the format underspecified — JWS has multiple modes (detached payload, JSON serialization, compact serialization), and the spec did not pin down which mode or how the payload relates to the response body. Two independent implementations reading the same spec could produce incompatible signatures.
The protocol already uses JCS (RFC 8785) for canonical JSON serialization elsewhere. The JWKS endpoint for key publication does not depend on JWS — it follows RFC 7517 independently.
Decision
Drop JWS Compact Serialization for response signatures. Define the signature as a raw Ed25519 signature over the JCS-canonicalized response body, with a separate kid field in the response for key selection.
Signature Fields
The response body includes two fields:
| Field | Description |
|---|---|
kid | Key identifier matching a key in the authority's JWKS |
signature | Base64url-encoded raw Ed25519 signature (64 bytes, no padding) |
Signing Process
- Construct the response body with all fields except
signature - JCS-canonicalize the body (RFC 8785) — this includes
kid - Sign the canonical byte sequence with Ed25519
- Base64url-encode the 64-byte signature (no padding)
- Add the
signaturefield to the response
Verification Process
- Remove the
signaturefield from the response body - JCS-canonicalize the remaining body (which includes
kid) - Fetch the authority's JWKS, select the key matching
kid - Base64url-decode the signature
- Verify the Ed25519 signature over the canonical bytes
- Reject the response if verification fails
The kid field is part of the signed payload. An attacker cannot swap key identifiers without invalidating the signature.
Options Considered
A. Keep JWS and specify a detached JWS profile. Fully specifying the JWS usage (detached payload, required headers, serialization mode) would achieve interoperability. Adds JOSE library dependency and specification surface area for a feature the protocol does not need — the response body is already the payload.
B. Raw Ed25519 signature with separate kid (chosen). The simplest design. No JOSE dependency. One canonicalization scheme (JCS), one signing algorithm (Ed25519), one encoding (base64url). Any implementation that can canonicalize JSON and call Ed25519 sign/verify achieves interoperability.
C. Keep JWS Compact and move the signed payload out of the JSON body. Separates the signature from the response entirely (e.g., via HTTP header). Breaks the self-contained response model — cached or forwarded responses lose their signature.
Consequences
- Response signatures are deterministic: JCS canonicalization + Ed25519 over the resulting bytes
- No JOSE library required for signature verification — only JCS and Ed25519
- The JWKS endpoint and key rotation mechanism use RFC 7517
- RFC 7515 (JWS) is not a normative dependency for response signatures
- If JOSE tooling is needed later, a fully specified detached-JWS profile can be added as an alternative verification method (see roadmap)
References
- Security specification — Response signature requirements
- API specification — Response format and fields
- ADR-007 — Security and Anti-Gaming (original signature decision)
- RFC 8785 — JSON Canonicalization Scheme (JCS)
- RFC 8037 — CFRG Elliptic Curve Signatures (Ed25519)
- RFC 7517 — JSON Web Key (JWKS, unchanged)