Security Considerations
Status and normative language: See Status of This Document.
This document defines normative implementation security requirements. threat-model.md provides informative attack analysis.
1. Key Management
- Issuer signing keys SHOULD be generated and stored in hardware-backed or otherwise isolated key storage. The signing key does not need to be present on the web server that serves
/.well-known/osap.json. - Issuers SHOULD use per-purpose keys (e.g. a key for attestations, another for revocation lists) and SHOULD rotate keys periodically using
valid_from/valid_until(identity.md § 5), so that a future compromise bounds the exposure window. - Old public keys MUST remain published after rotation so historical attestations stay verifiable (identity.md § 5).
- Issuers SHOULD rehearse the compromise response defined in identity.md § 6.
- A compromised trust bundle maintainer key can alter bundle interpretations for bundle users. The same storage and rotation guidance applies.
2. Signature Malleability
- Implementations MUST use Ed25519 libraries that reject non-canonical signatures (e.g. RFC 8032 strict verification with canonical encoding checks).
- Verifiers MUST require
proofValueto decode to exactly 64 bytes of unpadded base64url and MUST reject padded, oversized, or otherwise non-canonical encodings (envelope.md § 6.2). - Implementations MUST NOT use
proofValueas a unique key. The attestation identity for deduplication is (issuer.id,id); signature variants could otherwise create distinct duplicates.
3. Canonicalization Pitfalls
Implementations must produce identical JCS (RFC 8785) bytes. Relevant failure sources include:
- Canonicalizer implementation. Key sorting alone does not implement JCS. Number serialization (shortest round-trip form per ECMAScript), string escaping, and UTF-8 handling have exact rules. Implementations MUST use a tested JCS library or validate against the RFC 8785 test vectors.
- Non-integer numbers. Floating-point values are where serializers disagree most; issuers SHOULD prefer strings or integers in claim values (envelope.md § 7).
- Unicode normalization. JCS does not normalize Unicode; visually identical strings in NFC and NFD canonicalize differently. Issuers SHOULD emit NFC.
- Signing input. The signing input is the whole document with only
proof.proofValueremoved, not the document withoutproofor theproofalone (envelope.md § 6.1). Cross-implementation test vectors are listed in conformance.md. - Duplicate JSON keys. Parsers differ in whether the first or last duplicate value takes precedence. Implementations SHOULD reject JSON documents containing duplicate object keys.
4. Time Source Trust
Verification uses time for key validity windows, trust-period boundaries, attestation validity windows, and current-status evaluation.
- The verifier's clock is a trust dependency. A skewed or attacker-controlled clock shifts trust-period evaluation and key-validity decisions. Verifiers SHOULD use a reliable time source and SHOULD tolerate small skew (minutes, not days) at period boundaries.
- Timestamps inside OSAP documents (
issued_at,proof.created,valid_from,revoked_at, …) are assertions by their signers, not independently established facts. The transparency log extension area provides the only independent chronology evidence in OSAP (transparency-logs.md). - Verifiers MUST NOT treat
issued_atas proof of when an attestation was created (temporal-trust.md § 3).
5. Replay of Old Attestations
An OSAP attestation is not bound to a presentation context; anyone can re-present a genuine old attestation at any time.
- Replaying an old attestation with its matching asset reproduces the verification result, including any subsequently issued revocation or correction. The verification algorithm therefore includes the revocation check (verification.md § 3, Step 6) and correction presentation. Current revocation and correction data address stale evidence; attestation expiry does not.
- Replaying an attestation against different bytes fails the fingerprint check ("Asset hash does not match signed fingerprint").
- Presenting an old attestation as applying to a later event creates a contextual risk. OSAP surfaces timestamps and, where available,
ContextAttestations from other issuers (claims.md § 4.5). Verifiers SHOULD displayissued_atprominently.
6. Expired Keys vs Historical Validity
A signature made while a key was valid remains historically verifiable after the key expires.
- Key validity is evaluated at the attestation's
issued_at, not at verification time (identity.md § 5). Expiry of a key MUST NOT retroactively invalidate attestations issued during its validity window. - Verifiers MAY add an info-level note that the signing key has since expired, but MUST NOT report the signature as invalid on that basis.
- A revoked key indicates an adverse event. Attestations dated during the pre-revocation window receive a warning because a key holder can backdate
issued_at(identity.md § 6, threat-model.md § 4). - Under temporal-trust evaluation, historical and current status are evaluated separately (temporal-trust.md). Key expiry and current distrust do not change historical status.
7. Transport Security
- All OSAP fetches (issuer metadata, sidecars, revocation lists, bundles, lookups) MUST use HTTPS with certificate validation (identity.md § 3). For
did:web, accepting an invalid certificate breaks the identity binding. - HTTPS authenticates the serving domain and protects transport; it does not independently authenticate document contents. Envelopes and bundles carry signatures, and revocation lists can carry signatures.