Files
suaveplan/openspec/changes/_superseded-narrow-deferrals-2026-05-17/add-webauthn-mds3/tasks.md
2026-05-27 23:29:53 +01:00

99 lines
6.6 KiB
Markdown

# 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/`.