fix(auth): honor typed passkey credential config#17
Merged
Conversation
3-phase plan: BMW 500 hotfix, plugin v0.3.0 admin bootstrap steps, BMW migration onto plugin auth. SSO IDP deferred to Phase II. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Resolves 4 Critical + 8 Important findings. Adopts magic-link reuse (no new step types/migration/HKDF/module type); broadens Phase 1 to exhaustive nil-deref audit covering signup; defers generate_token retirement; resolves all rev-1 hedges in-design. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Drops all plugin work (YAGNI). All 4 PRs land in buymywishlist: - PR-0: BMW engine bump v0.20.1 -> v0.51.6 (likely real 500 source) - PR-1: exhaustive nil-deref hotfix - PR-2: admin bootstrap pipelines + magic_link_tokens reuse + super_admin SQL seed - PR-3: bespoke -> plugin password step rename (keep generate_token) Phase II = plugin extraction when 2nd consumer arrives. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Cycle 3 surfaced 5 Critical findings, mostly fact errors in rev 3.
Skill cap (2 revisions) reached; per autonomous-mode mandate, applying
mechanical fixes without re-running cycle 4 adversarial review:
- bcrypt cost regression: drop hash_password swap (plugin DefaultCost=10
vs bespoke=12); keep bespoke. Phase II opens plugin v0.2.5 with
configurable cost.
- magic_link_generate ignores expiry_minutes (hardcoded 15): use 15 min.
- Role schema corrected to actual ('user'/'admin'/'super_admin'/
'moderator'/'support').
- generate_token call-site count corrected (9 not 10).
- Timing oracle accepted with note (operator-only endpoint).
- Bootstrap-redeem switched POST + token-hash binding.
- Existing magic-link queries gain purpose='login' filter.
- Phase II 1-page interface sketch added per user soft ask.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Per plan-phase cycle 3 adversarial review: URL returned in response body (not log), redeem endpoint GET (browser-clickable, matching existing /auth/magic-link pattern). Trade-off documented. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
BMW http.server binds :8080 all-interfaces; Tailscale exposes :443. Bearer token is sole protection. Strengthened via min-entropy (>=32) and rate-limit rules in plan rev 6. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…te counts Both bespoke steps have 2 call sites each (not 1). hash_password: :881 + :11116; verify_password: :1073 + :9447. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…ming-oracle row Rev 6 amendment claimed 'dropped throughout' but missed 4 places: Goal §2, Top Doubts timing row, Top Doubts allowlist row, Assumption #2. All updated to 'bearer-token-gated' or 'all-interfaces publicly reachable'. Bootstrap-link response shape reconciled: rev 5 plan moved URL to body (URL on hit / 404 on miss) — design row updated to match instead of claiming 'constant 200 timing-equalisation'. Rate-limit limitation documented (engine no-op per modules.go:139-174). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Rev-8 amendment header claimed scrub-throughout but missed:
- §3 'configured to bind localhost-only via existing BMW ingress'
- §3 allowlist branches 'SAME response' (now 200/404 split)
- §3 URL 'embedded in operator-facing log entry' (now in body)
- §4 'POST /admin/bootstrap-redeem' + 'Body: {token}' (now GET +
query params per rev-5 amendment)
- §6 'curl --unix-socket /var/run/bmw.sock' (now TCP)
All three sections rewritten to reflect actual plan rev 11
implementation: publicly-reachable, GET redeem, NEW enrol-passkey
pipelines (additive), 24h JWT expiry in config block, SQL-side
expires_at filter, case-insensitive email.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…g GET handler Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…correct v0.51.6 → v0.51.2 pin Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Cycle-14 deferred PR-3 in the header amendment but the body still had a full active PR-3 section + verification gate + rollback row + sequencing row + file touch row. Cycle-15 caught the drift. All updated to reflect Phase II deferral. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…s, References, Assumption #5) Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Accept snake_case strict-proto credential config and derive RP ID before optional modules decide whether to unregister.
Updates release manifest URLs so the v0.2.5 tag can pass GoReleaser's manifest-version gate and publish installable artifacts.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Dependencies
Verification