# Capability Spec Delta: webauthn (webauthn) **Package**: `@suaveplan/webauthn` **Status**: PROPOSED (companion delta of `add-webauthn-mds3`) > Every requirement below carries a `**Verified by:**` line at authoring time. No exceptions. ## MODIFIED Requirements ### Requirement: Attestation verification dispatch The package SHALL export `verifyAttestation(input: VerifyAttestationInput): Promise` from the `./verifier` subpath. The function SHALL dispatch on `input.attestationObject.fmt` to the per-format verifier registered in `input.registry`, throwing `WEBAUTHN.ATTESTATION_FORMAT_UNSUPPORTED` when no verifier is registered. `VerifyAttestationInput` SHALL accept an optional `metadata?: MetadataResolver` field (typed via `import type` from `@suaveplan/webauthn-mds3` — runtime-optional) and an optional `revokedStatuses?: ReadonlySet` field. `AttestationVerifyResult` SHALL carry an optional `metadata?: MetadataLookup` field. When `input.metadata` is `undefined` the returned `AttestationVerifyResult` SHALL be byte-identical to the pre-modification contract (strict back-compat). When `input.metadata` is supplied, after the per-format verifier returns, `verifyAttestation` SHALL resolve the AAGUID — or, for `fmt === "fido-u2f"` or an all-zero AAGUID, the SHA-1 SKI of the leaf attestation certificate (FIDO MDS3 §3.1.6) — call `resolveByAaguid` / `resolveByAttestationCertificateKeyId` on the supplied resolver, set `result.metadata` to the returned `MetadataLookup` (or omit when `undefined`), and downgrade `result.trusted` to `false` when the lookup's `currentStatus` is in `revokedStatuses ?? DEFAULT_REVOCATION_STATUSES`. #### Scenario: dispatches to registered format verifier - **WHEN** `verifyAttestation({ attestationObject: { fmt: "packed", ... }, registry: defaultAttestationRegistry(), ... })` is called - **THEN** the result is produced by the `packed` verifier and includes `trustPath`, `attestationType`, `trusted` #### Scenario: throws WEBAUTHN.ATTESTATION_FORMAT_UNSUPPORTED on unknown fmt - **WHEN** `verifyAttestation({ attestationObject: { fmt: "unknown-fmt", ... }, registry: emptyRegistry })` is called - **THEN** the call rejects with `WEBAUTHN.ATTESTATION_FORMAT_UNSUPPORTED` #### Scenario: omits metadata field when no resolver injected (back-compat) - **WHEN** `verifyAttestation(input)` is called with `input.metadata === undefined` - **THEN** the resolved `AttestationVerifyResult` has `metadata === undefined` and is byte-for-byte identical to the legacy (pre-modification) result for the same inputs #### Scenario: augments result with metadata when resolver injected - **GIVEN** a `MetadataResolver` whose `resolveByAaguid` returns a `MetadataLookup` with `currentStatus === "FIDO_CERTIFIED_L1"` - **WHEN** `verifyAttestation({ ..., metadata: resolver })` is called against a `packed` attestation carrying a known AAGUID - **THEN** `result.metadata` deep-equals the lookup and `result.trusted` is the verifier's original value (unchanged) #### Scenario: downgrades trusted=false when currentStatus is revoked - **GIVEN** a `MetadataResolver` whose `resolveByAaguid` returns a `MetadataLookup` with `currentStatus === "REVOKED"` - **WHEN** `verifyAttestation({ ..., metadata: resolver })` is called and the per-format verifier returned `trusted: true` - **THEN** the merged `result.trusted` is `false` and `result.metadata.currentStatus === "REVOKED"` #### Scenario: resolves U2F by attestation-cert SKI - **GIVEN** a `MetadataResolver` and a `fido-u2f` attestation whose leaf cert has SKI `0xDEAD…` - **WHEN** `verifyAttestation({ ..., metadata: resolver })` is called - **THEN** the resolver's `resolveByAttestationCertificateKeyId(0xDEAD…)` is invoked exactly once and `resolveByAaguid` is never called **Verified by:** `packages/auth/webauthn/src/verifier/verify-attestation.test.ts::"dispatches to registered format verifier"` AND `packages/auth/webauthn/src/verifier/verify-attestation.test.ts::"throws WEBAUTHN.ATTESTATION_FORMAT_UNSUPPORTED on unknown fmt"` AND `packages/auth/webauthn/src/verifier/verify-attestation.test.ts::"omits metadata field when no resolver injected (back-compat)"` AND `packages/auth/webauthn/src/verifier/verify-attestation.test.ts::"augments result with metadata when resolver injected"` AND `packages/auth/webauthn/src/verifier/verify-attestation.test.ts::"downgrades trusted=false when currentStatus is revoked"` AND `packages/auth/webauthn/src/verifier/verify-attestation.test.ts::"resolves U2F by attestation-cert SKI"`