Files
2026-05-27 23:29:53 +01:00

6.6 KiB

Tasks — add-webauthn-mds3

1. Package scaffolding

  • 1.1 Create packages/auth/webauthn-mds3/ per genesis package layout.
  • 1.2 package.json at version: 0.0.0, sideEffects: false, workspace:^ for internal deps, catalog:* for external.
  • 1.3 tsconfig.json extending @suaveplan/typescript-config universal preset.
  • 1.4 vitest.config.ts using createTestConfig() from @suaveplan/testing/config; coverage thresholds 100 / 100 / 100 / 100; provider: 'istanbul'.
  • 1.5 Subpath exports map in package.json: ., ./fetch, ./verify, ./cache, ./refresher, ./errors.
  • 1.6 Root README.md with one-paragraph description, install, quick-start, Modules section linking to every co-located .md.

2. Constants + FIDO root pinning

  • 2.1 src/constants/fido-root.ts + .md — pin the FIDO Alliance MDS3 root CA DER bytes + SHA-256 fingerprint; export FIDO_MDS3_DEFAULT_URL, DEFAULT_REFRESH_INTERVAL_MS, DEFAULT_REVOCATION_STATUSES.

3. Error codes

  • 3.1 src/errors/error-codes.ts + .md — defineCodes("WEBAUTHN_MDS3", [...]) with every code from the spec delta; export WebAuthnMds3Error.
  • 3.2 src/errors/errors.test.ts — assert every code is reachable from a production path (call-site grep harness).

4. Schemas

  • 4.1 src/schemas/metadata-blob.schemas.ts + .md — MetadataBlobPayloadSchema, MetadataStatementSchema, AuthenticatorStatusSchema, StatusReportSchema, BiometricStatusReportSchema, EcdaaTrustAnchorSchema, MetadataBlobEntrySchema tracking FIDO MDS3 §3.1.

5. Fetch

  • 5.1 src/fetch/fetch-blob.ts + .md — fetchMetadataBlob({ fetch, url?, signal? }); maps non-2xx → BLOB_FETCH_FAILED; honors AbortSignal.
  • 5.2 src/fetch/fetch-blob.test.ts — happy path; non-2xx; abort.

6. Verify

  • 6.1 src/verify/verify-blob.ts + .md — verify compact JWS via @suaveplan/jws; pin alg allow-list (RS256, ES256, ES384); validate x5c chain to FIDO root via @suaveplan/x509; check nextUpdate; decode + Zod-validate payload.
  • 6.2 src/verify/verify-blob.test.ts — happy, signature-flipped, chain-broken, expired, alg-disallowed, schema-mismatch (use sample-blob fixture).

7. Cache

  • 7.1 src/cache/metadata-cache.ts + .md — wraps injected StorageLike<MetadataBlobPayload> with key namespace webauthn-mds3:blob:v1; surfaces CACHE_READ_FAILED / CACHE_WRITE_FAILED.
  • 7.2 src/cache/metadata-cache.test.ts — round-trip; injected storage failure mapping.

8. Refresher

  • 8.1 src/refresher/metadata-refresher.ts + .md — createMetadataRefresher({ fetch, storage, clock, logger, intervalMs?, signal? }); reentrancy guard; OTel counter; jittered scheduling at nextUpdate - jitter.
  • 8.2 src/refresher/metadata-refresher.test.ts — schedule, reentrancy guard, abort, OTel counter, fallback to intervalMs.

9. Resolver

  • 9.1 src/resolver/types.ts + .md — MetadataResolver, MetadataLookup interfaces (no name collisions per AGENTS.md §10 — folder is resolver/, files use feature names not *-resolver.ts).
  • 9.2 src/resolver/memory.ts + .md + memory.test.ts — createMemoryResolver for verified payloads.
  • 9.3 src/resolver/cached.ts + .md + cached.test.ts — createCachedResolver reading the cache + optional refresher drive.

10. Observability

  • 10.1 src/observability/metrics.ts + .md — webauthn_mds3.refresh_total{outcome}, webauthn_mds3.lookup_total{outcome} counters; webauthn_mds3.blob_age_ms histogram. No-op when no exporter.
  • 10.2 src/observability/metrics.test.ts — every metric records on its production path against an in-memory MeterProvider.

11. Fixtures

  • 11.1 src/__fixtures__/mds3-sample-blob.jwt — captured FIDO Alliance MDS3 conformance-suite sample blob.
  • 11.2 src/__fixtures__/mds3-corrupted-blob.jwt — signature-flipped variant for negative tests.
  • 11.3 src/__fixtures__/index.ts — typed fixture exports.

12. Benchmarks

  • 12.1 src/__benchmarks__/verify-blob.bench.ts — JWS verify throughput on the sample blob.
  • 12.2 src/__benchmarks__/resolve-aaguid.bench.ts — AAGUID lookup throughput.

13. Integration into @suaveplan/webauthn

  • 13.1 Extend VerifyAttestationInput with optional metadata?: MetadataResolver field (typed via import type from @suaveplan/webauthn-mds3 — no runtime dep).
  • 13.2 Extend AttestationVerifyResult with optional metadata?: MetadataLookup field.
  • 13.3 Wire post-verifier resolution: AAGUID for non-U2F formats, attestation-cert SKI for fido-u2f; downgrade trusted=false on revoked statuses; configurable revocation set with default from DEFAULT_REVOCATION_STATUSES.
  • 13.4 Update packages/auth/webauthn/src/verifier/verify-attestation.test.ts — three new tests: resolver injected augments result; revoked status downgrades trust; no resolver = byte-identical legacy behaviour.
  • 13.5 Refresh packages/auth/webauthn/src/verifier/verify-attestation.md and the three attestation doc anchors (packed.md, fido-u2f.md, none.md) so the "caller wires MDS3" language now mentions MetadataResolver as the canonical seam.
  • 13.6 Add @suaveplan/webauthn-mds3 to packages/auth/webauthn/README.md Modules section as the recommended MDS3 sidecar.

14. Pre-publish gate

  • 14.1 bunx turbo lint typecheck test --filter=@suaveplan/webauthn-mds3 green.
  • 14.2 bunx turbo test:coverage --filter=@suaveplan/webauthn-mds3 100 / 100 / 100 / 100.
  • 14.3 bunx turbo lint typecheck test --filter=@suaveplan/webauthn green (dependent sweep — §13 step 10).
  • 14.4 Banned-pattern scan: zero matches per §13 step 4.
  • 14.5 Barrel-shape scan (§13 step 4a): zero matches.
  • 14.6 Test-runner import scan (§13 step 4b): zero matches.
  • 14.7 Missing-.md scan: zero misses.
  • 14.8 bunx markdownlint-cli2 --fix then second pass with no --fix exits 0.

15. Repo-root manifest refresh (§13b)

  • 15.1 bun scripts/folder-reorg/generate-manifest.ts → MANIFEST.md refreshed.
  • 15.2 bun scripts/generate-missing.ts → MISSING.yml refreshed.
  • 15.3 STATUS.md updated: add @suaveplan/webauthn-mds3 row.
  • 15.4 SUMMARY.md paragraph for webauthn-mds3 added.

16. Fold + archive

  • 16.1 Fold specs/webauthn-mds3/spec.md into openspec/specs/webauthn-mds3/spec.md.
  • 16.2 Fold specs/webauthn/spec.md ## MODIFIED Requirements into the canonical openspec/specs/webauthn/spec.md.
  • 16.3 Move openspec/changes/add-webauthn-mds3/ → openspec/archive/<yyyy-mm-dd>-add-webauthn-mds3/.