auth-factor-design
Decision aid for authentication factor architecture — have/know/are mapping, coercion resistance, FIDO2 PIN/UV policy, and PRF hot-path anti-patterns.
What this skill does
# auth-factor-design Decision aid for authentication factor architecture. Use when designing or reviewing any system whose unlock, login, or operation gating depends on more than one factor — and especially when biometrics, hardware tokens, or "something you know" enter the design. The skill forces three explicit exercises: a **factor inventory**, a **coercion-resistance matrix**, and a **lockout/recovery policy**. Without all three, the design isn't complete. ## Triggers - "factor design" / "MFA" / "multi-factor" - "FIDO2 PIN" / "WebAuthn PIN" - "biometric policy" / "uv=true" - "coercion resistance" / "rubber-hose" - "PRF hot path" / "hmac-secret" - "what you know vs what you have" - "duress code" / "duress factor" ## When NOT to use this skill - Pure password-based authentication for low-stakes systems (use OWASP ASVS L1 guidance) - OAuth/OIDC client design (different layer; use `sdlc-complete` security-architect for protocol selection) - Network-layer mutual TLS (cert authentication, not user authentication) --- ## Section 1: The three factor classes | Class | Examples | What "knowing it" means | |---|---|---| | **Have** | Hardware token, USB drive, smart card, phone with attestation | Possession demonstrates auth | | **Know** | Password, PIN, passphrase, recovery code, pattern, security questions | Recall demonstrates auth | | **Are** | Fingerprint, face, voice, gait, behavioral biometrics | Body demonstrates auth | A "true" multi-factor system requires factors from at least **two distinct classes**. Three of the same class is not multi-factor — two passwords is one factor twice. ### Common misclassifications - **SMS code**: not a "have" factor on its own — SIM-swappable, network-interceptable. Treat as a weak channel-bound code, not a possession proof. - **TOTP from phone**: weak "have" if phone is uncontrolled (any app can read TOTP seed if leaked). Stronger if seed is in a hardware-backed enclave (Apple Secure Enclave, Android Strongbox). - **Email confirmation link**: not a factor — it's a recovery channel that demonstrates control of the email account, which itself depends on factors. - **"Security question" answers**: nominally "know" but socially harvestable; treat as a fallback recovery hint, not a factor. --- ## Section 2: Factor inventory exercise (mandatory) Before declaring an auth design complete, fill out: | Factor | Class | Specific instance | Required for which operations? | Lost-recovery procedure | |---|---|---|---|---| | YubiKey 5 OTP slot | have | hardware HMAC-SHA1 PRF | unlock, secret derivation | revoke at HQ, reissue | | YubiKey Bio (FIDO2 PRF) | are+have | fingerprint + hmac-secret w/ uv=true | unlock, signing | revoke + reissue (≤4 weeks per fingerprint enrollment) | | FIDO2 PIN | know | PIN on Bio key | required when `uv=true` | reset via reset-protocol; bricks key after N failures | | Recovery passphrase | know | 6-word BIP39 phrase | emergency rotation only | offline backup at HQ | **Required**: at least one row from each of two classes for any operation that protects high-value assets. Document operations that bypass this rule with explicit risk acceptance. --- ## Section 3: Coercion-resistance matrix (mandatory) For each factor, document whether it can be coerced and what mitigates the coercion. | Factor | Coercible? | How | Mitigation | |---|---|---|---| | Password / PIN | Yes — operator under duress reveals it | Mitigation: duress code that triggers fail-closed silent lockout | | Hardware token | Yes — physical seizure | Mitigation: time-lock, witness requirement, second-factor at HQ | | Biometric | **Always coerced**. Operator's body is present; "extracting" the biometric is trivial under duress | Mitigation: pair with a "know" factor (FIDO2 PIN) so coerced biometric alone fails | | Geolocation | Coercible (move operator) | Mitigation: not a real factor; use as risk signal only | ### Anti-pattern: only have + are (review finding H2) A system with hardware token + biometric and **no "know" factor** is not coercion-resistant. The attacker compels the operator to come to the device with the token in hand and the finger ready. There is nothing the operator can decline to provide. A FIDO2 PIN as the third factor — REQUIRED for PRF assertion via `uv=true` — adds: - A factor only the operator's mind contains (truly something they "know") - A lockout-after-N-tries property (FIDO2 PIN bricks the key after retries; default ~8) - Optional duress codes (some authenticators support a separate "wipe key on this PIN" entry) Cost: zero hardware. Recommended for any production deployment of FIDO2/WebAuthn PRF. --- ## Section 4: FIDO2 / WebAuthn PRF design ### Suggested default For hardware-backed authenticated key derivation: - **FIDO2 hmac-secret extension** (PRF in WebAuthn-2 terminology) on a token with both PIN and biometric - **`uv: required`** in the assertion — forces user verification - **PIN required** — forces "know" alongside "have+are" - **Per-RP credential isolation** — different RP IDs derive different PRF outputs ### Tooling | Use case | Suggested tool | Vetted alternatives | |---|---|---| | Production C/C++ | **libfido2** (Yubico's reference C lib) | `python-fido2` only behind a sandbox; PyHanko/cose for high-level signing | | FIDO2 CLI | **`fido2-token`, `fido2-assert`** (libfido2 binaries) | OpenSC for smart-card-style use | | Browser-side WebAuthn | Web Crypto API + `navigator.credentials.create/get` | Server libs: `webauthn4j` (JVM), `simplewebauthn` (Node), `python-fido2` (server) | | Testing | Yubico's `fido2-token -L`, virtual authenticators (Chrome devtools, soft-fido2) | Hardware test rigs only for pre-production validation | ### Anti-pattern: Python in the PRF hot path (review finding H3) `python-fido2` in the **biometric PRF assertion path** introduces a wide attack surface for the most sensitive operation in the system: - `python-fido2`, `cryptography`, `cffi`, `pyusb` — any of these getting a typosquat or supply-chain compromise = PRF interception - The C path through `libfido2` is ~50KB statically linkable, audited, fewer transitive deps **Remediation options:** 1. **Use `libfido2` C binaries** (`fido2-token`, `fido2-assert`) directly — they support `hmac-secret`. Drop Python from the hot path entirely. 2. **If Python is mandatory**: vendor and pin `python-fido2` + transitive deps with hash-locked wheels in your bootstrap; verify per-wheel SHA-256 against an offline manifest; reproducibly build the bootstrap. 3. **Either way**: run the PRF call inside a sandboxed namespace (bubblewrap, no network, no `/proc`, read-only mounts). ### RP ID guidance `rp.id` in WebAuthn / FIDO2 is canonically a domain name. Some authenticators behave oddly with non-domain RP IDs (e.g., "agent-box"). For non-web contexts: - Prefer a domain you control even if not actually web-served (`agent-box.example.com`) - Test with multiple authenticator firmware versions before locking RP ID - Document if you proceed with non-domain (review L1 finding) --- ## Section 5: Lockout / retry policy | Factor | Failure response | |---|---| | FIDO2 PIN | Hard lockout after N failures (default ~8); brick key on M (default 3 lockout cycles); requires reset protocol with PIN+attestation | | Biometric on hardware token | Fall back to PIN (if PIN set); on N failures of bio, force PIN; never "skip bio" | | Application password | Rate-limit + account lock with side-channel notification; CAPTCHA after 3 failures (anti-bot, not anti-human) | | Recovery code (single-use) | Mark used immediately; rotate active set; alert on use | ### Required exercise: document the exact behavior For each authenticator in your system, document: ``` Factor: FIDO2 PIN on Bio key Wrong-PIN behavior: After 1: warning + 1-second delay After 3: 5-second delay After 5: 30-second delay After 8: full lockout, requires reset Lockout cycles before key brick: 3 (default) Reset procedure: fido2-token -R (factory reset, w
Related in Design
contribute
IncludedLocal-only OSS contribution command center. Auto-refreshes the user's in-flight PR and issue state on invoke so conversations start with full context — no need to brief Claude on what's in flight. Helps the user find issues to contribute to on GitHub, builds per-repo dossiers of what each upstream expects (CLA, DCO, branch convention, AI policy, draft-first, review bots, issue templates), runs deterministic gates before any external action so AI-assisted contributions don't reach maintainers as slop. State is markdown-only: candidate files at ~/.contribute-system/candidates/, repo dossiers at ~/.contribute-system/research/, append-only event log at ~/.contribute-system/log.jsonl. No database, no cloud calls. Use when the user asks about their PRs / issues / contributions, wants to find new work to take on, claim an issue, build/refresh a repo's dossier, or draft a Design Issue or PR. Trigger with "/contribute", "what's my PR status", "find a contribution", "claim issue X", "draft a Design Issue for Y", "refresh dossier for Z".
architectural-analysis
IncludedUser-triggered deep architectural analysis of a codebase or scoped subtree across eight modes — information architecture, data flow, integration points, UI surfaces, interaction patterns, data model, control flow, and failure modes. This skill should be used when the user asks to "diagram this codebase," "map the architecture," "show the data flow," "give me an ERD," "trace control flow," "find the integration points," "verify the layout pattern," "audit the UX architecture," or any similar request whose primary deliverable is mermaid diagrams plus cited reports under docs/architecture/. Dispatches haiku/sonnet sub-agents in parallel for per-mode exploration, then verifies every citation mechanically before any node lands in a diagram. Not for one-off prose explanations of code (use code-explanation) or for high-level system design from scratch (use system-design).
mcp
IncludedModel Context Protocol (MCP) server development and tool management. Languages: Python, TypeScript. Capabilities: build MCP servers, integrate external APIs, discover/execute MCP tools, manage multi-server configs, design agent-centric tools. Actions: create, build, integrate, discover, execute, configure MCP servers/tools. Keywords: MCP, Model Context Protocol, MCP server, MCP tool, stdio transport, SSE transport, tool discovery, resource provider, prompt template, external API integration, Gemini CLI MCP, Claude MCP, agent tools, tool execution, server config. Use when: building MCP servers, integrating external APIs as MCP tools, discovering available MCP tools, executing MCP capabilities, configuring multi-server setups, designing tools for AI agents.
react-native-skia
IncludedDesign, build, debug, and optimise high-polish animated graphics in React Native or Expo using @shopify/react-native-skia, Reanimated, and Gesture Handler. Use when the user wants canvas-driven UI, shaders, paths, rich text, image filters, sprite fields, Skottie, video frames, snapshots, web CanvasKit setup, or performance tuning for custom motion-heavy elements such as loaders, hero art, cards, charts, progress indicators, particle systems, or gesture-driven surfaces. Also use when the user asks for fluid, glow, glass, blob, parallax, 60fps/120fps, or GPU-friendly animated effects in React Native, even if they do not explicitly say "Skia". Do not use for ordinary form/layout work with standard views.
plaid
IncludedProduct Led AI Development — guides founders from idea to launched product. Six capabilities: Idea (discover a product idea), Validate (pressure-test the idea against fatal flaws, problem reality, competition, and 2-week MVP feasibility), Plan (vision intake + document generation), Design (translate image references into a design.md spec), Launch (go-to-market strategy), and Build (roadmap execution). Use when someone says "PLAID", "plaid idea", "help me find an idea", "product idea", "idea from my business", "idea from my expertise", "plaid validate", "validate my idea", "pressure-test", "is this idea good", "find fatal flaws", "validate the problem", "plan a product", "define my vision", "generate a PRD", "product strategy", "plaid design", "design from image", "translate image to design", "create design.md", "extract design tokens", "plaid launch", "go-to-market", "launch plan", "GTM strategy", "launch playbook", "plaid build", "build the app", "start building", or "execute the roadmap".
nextjs-framer-motion-animations
IncludedAdds production-safe Motion for React or Framer Motion animations to Next.js apps, including reveal, hover and tap micro-interactions, whileInView, stagger, AnimatePresence, layout and layoutId transitions, reorder, scroll-linked UI, and lightweight route-content transitions. Use when the user asks to add, refactor, or debug Motion or Framer Motion in App Router or Pages Router codebases, especially around server/client boundaries, reduced motion, LazyMotion, bundle size, hydration, or route transitions. Avoid for GSAP-style timelines, WebGL or 3D scenes, heavy scroll storytelling, or CSS-only effects unless Motion is explicitly requested.