Nhảy tới nội dung

Identity & Credentials

EDH identity is self-sovereign: there is no central authority that vouches for a user. That makes the verification step the entire security boundary. If a verifier accepts an assertion it did not actually check, an attacker can be anyone. Every requirement here exists to close the gap between "this assertion is well-formed" and "this assertion is authentic".

This page governs the did:bio authentication flow, Verifiable Credentials, and any wallet-signature challenge–response.

Authentication must verify a signature over a fresh challenge

IC-1 (MUST). Before issuing any authorization code, session, or token in response to a wallet/biometric authentication, the provider MUST verify the supplied signature against the public key of the claimed identity, over a server-issued, single-use, time-bound challenge nonce. If the signature does not verify, the flow MUST terminate with no credential issued.

Rationale. The challenge–response is the proof of key control. A flow that accepts a walletAddress (or DID) without verifying a signature over the server's nonce authenticates nothing — any caller can name any identity and receive a token for it. Because EDH identities are public (addresses appear on-chain), the set of impersonable identities is the entire user base.

Conformance check. Replay a completed authentication with the signature field removed or corrupted, and with a walletAddress you do not control. The provider MUST reject it. Submit a response whose challengeId has already been consumed; it MUST be rejected (see IC-4).

Authentication context must report only verified factors

IC-2 (MUST). The Authentication Methods Reference (amr) and any assurance-level claim in an issued token MUST reflect only factors the provider actually verified in that exchange. A factor (e.g. wallet_sig, bio_liveness) MUST NOT be asserted on the basis that it was expected.

Rationale. Relying parties make authorization decisions from amr/assurance claims. Asserting wallet_sig while skipping the signature check (IC-1) does not just fail to authenticate — it actively misinforms downstream consumers, who will grant access believing a stronger factor was present than was.

Credential verification must bind the signature to the issuer

IC-3 (MUST). When verifying a credential whose proof is a wallet/EIP-191 signature, the verifier MUST resolve the credential's issuer DID to its authorized signing key and require that the key recovered from the signature equals that authorized key. Recovering a valid key from the signature is not sufficient. A credential whose recovered signer is not an authorized key of the named issuer MUST be treated as invalid.

Rationale. EIP-191 recovery always yields some address for a well-formed signature. If the verifier stops at "a signature was recovered" and returns valid, then an attacker signs an arbitrary credential body with their own key, sets issuer to any trusted DID, and the credential verifies. This is universal forgery: every "trusted issuer" can be impersonated. The trusted-issuer allowlist is meaningless unless the signature is bound to that issuer's key. DID-to-key resolution MUST be performed inside the verifier, not deferred to the caller — a caller that forgot to re-check is the common failure mode.

Conformance check. Construct a credential with issuer set to a known-trusted DID, signed with a freshly generated key unrelated to that DID. Verification MUST return invalid.

Server / OIDC signatures must be cryptographically verified

IC-4 (MUST). Tokens or credential proofs that are JWS/OIDC artifacts MUST be verified against the issuer's published keys (e.g. the provider JWKS at its well-known endpoint), including signature, iss, aud, and expiry. Structural validation (shape, segment count, presence of fields) is NOT verification and MUST NOT be treated as such.

Rationale. A three-segment, dot-separated string is trivially fabricated. Only a signature check against the issuer's key establishes authenticity. Accepting a structurally well-formed token is equivalent to accepting an unsigned one.

Challenges must be single-use, bound, and expiring

IC-5 (MUST). Authentication challenges MUST be: (a) single-use — consumed atomically on first successful exchange and rejected thereafter; (b) time-bound — rejected after a short expiry; and (c) bound to the requesting client_id and redirect_uri, validated at exchange time.

Rationale. Without single-use enforcement, a captured response can be replayed. Without client_id/redirect_uri binding, a code obtained for one relying party can be redirected to another (code injection). Short expiry bounds the window for any of the above.

Summary

IDRequirementPrevents
IC-1Verify signature over a fresh, single-use challenge before issuing anythingImpersonation of any identity
IC-2Report only verified factors in amr/assuranceMisleading relying parties into over-authorizing
IC-3Bind the recovered signer to the issuer's authorized keyUniversal credential forgery
IC-4Cryptographically verify JWS/OIDC tokens, not just their shapeAcceptance of fabricated tokens
IC-5Single-use, expiring, client-bound challengesReplay and code-injection