Add admin passkey management #53

Closed
opened 2026-05-22 11:43:11 -05:00 by erik · 3 comments
Owner

Goal

Let an already authenticated site owner register, list, and delete admin passkeys through the admin UI. Passkeys are not the bootstrap login mechanism; they are enrolled after the owner has authenticated through the magic-link session flow.

Spec: docs/web-specs/03-admin-auth-keys-passkeys.md

Requirements

  • Add passkey credential storage compatible with future WebAuthn authentication.
  • Add authenticated admin UI for passkey registration, listing, and deletion.
  • Generate WebAuthn registration options only for an authenticated owner session.
  • Verify registration responses before storing passkey public keys/credential IDs.
  • Protect passkey management behind the admin session from task-8af07ab8.
  • Do not add passkey login in this slice.
  • Do not add multi-role permissions or scoped API keys in this slice.

Acceptance criteria

  • Authenticated site owner can register a passkey.
  • Authenticated site owner can list registered passkeys.
  • Authenticated site owner can delete a passkey.
  • Anonymous users cannot access passkey management routes or registration options.
  • Stored passkeys do not include private key material.
  • Tests cover registration option protection, registration verification behavior where practical, listing, deletion, and protected access.
  • Relevant lint/test checks pass.

Dependencies

  • task-8af07ab8
## Goal Let an already authenticated site owner register, list, and delete admin passkeys through the admin UI. Passkeys are not the bootstrap login mechanism; they are enrolled after the owner has authenticated through the magic-link session flow. Spec: `docs/web-specs/03-admin-auth-keys-passkeys.md` ## Requirements - Add passkey credential storage compatible with future WebAuthn authentication. - Add authenticated admin UI for passkey registration, listing, and deletion. - Generate WebAuthn registration options only for an authenticated owner session. - Verify registration responses before storing passkey public keys/credential IDs. - Protect passkey management behind the admin session from `task-8af07ab8`. - Do not add passkey login in this slice. - Do not add multi-role permissions or scoped API keys in this slice. ## Acceptance criteria - [ ] Authenticated site owner can register a passkey. - [ ] Authenticated site owner can list registered passkeys. - [ ] Authenticated site owner can delete a passkey. - [ ] Anonymous users cannot access passkey management routes or registration options. - [ ] Stored passkeys do not include private key material. - [ ] Tests cover registration option protection, registration verification behavior where practical, listing, deletion, and protected access. - [ ] Relevant lint/test checks pass. ## Dependencies - task-8af07ab8
Author
Owner

Synced from todu comment by @todu on 2026-06-04T19:54:32.923Z

PR Review

PR #100 reviewed against acceptance criteria.

Result: approved

Verification:

  • make check passed.
  • ./scripts/pre-pr.sh passed.
  • npm audit reports 0 vulnerabilities.
  • Forgejo Actions run 130 completed successfully.

Blocking issues: 0
Warnings: 0
Acceptance criteria: 7/7 met

Stopped at human merge approval gate.

_Synced from todu comment by @todu on 2026-06-04T19:54:32.923Z_ ## PR Review PR #100 reviewed against acceptance criteria. Result: approved Verification: - `make check` passed. - `./scripts/pre-pr.sh` passed. - `npm audit` reports 0 vulnerabilities. - Forgejo Actions run 130 completed successfully. Blocking issues: 0 Warnings: 0 Acceptance criteria: 7/7 met Stopped at human merge approval gate.
Author
Owner

Synced from todu comment by @todu on 2026-06-04T20:03:14.367Z

Completed

Acceptance criteria verified:

  • Authenticated site owner can register, list, and delete admin passkeys through the admin UI.
  • Anonymous users are redirected away from passkey management routes and registration options.
  • Stored passkey records contain credential IDs, public keys, counters, transports, and metadata only; no private key material.
  • Tests cover protected access, registration options, registration verification/storage behavior, failed verification, listing, deletion, and stored material.
  • Passkey login, multi-role permissions, and scoped API keys remain out of scope.

PR #100 was merged into main. Verification passed: make check, ./scripts/pre-pr.sh, npm audit, Forgejo Actions, and manual localhost passkey testing.

_Synced from todu comment by @todu on 2026-06-04T20:03:14.367Z_ ### Completed Acceptance criteria verified: - Authenticated site owner can register, list, and delete admin passkeys through the admin UI. - Anonymous users are redirected away from passkey management routes and registration options. - Stored passkey records contain credential IDs, public keys, counters, transports, and metadata only; no private key material. - Tests cover protected access, registration options, registration verification/storage behavior, failed verification, listing, deletion, and stored material. - Passkey login, multi-role permissions, and scoped API keys remain out of scope. PR #100 was merged into `main`. Verification passed: `make check`, `./scripts/pre-pr.sh`, `npm audit`, Forgejo Actions, and manual localhost passkey testing.
Author
Owner

Synced from todu comment by @todu on 2026-06-04T20:02:24.988Z

Manual Test Update

Manual localhost passkey testing has been completed.

Result: approved

Notes:

  • Passkey management works from localhost / secure origins.
  • LAN HTTP origins such as http://10.10.1.197:3000 cannot register passkeys because WebAuthn requires HTTPS or localhost.
  • The UI now explains the secure-origin requirement instead of saying the browser does not support passkeys.

Current gate: waiting for explicit human merge approval.

_Synced from todu comment by @todu on 2026-06-04T20:02:24.988Z_ ## Manual Test Update Manual localhost passkey testing has been completed. Result: approved Notes: - Passkey management works from localhost / secure origins. - LAN HTTP origins such as `http://10.10.1.197:3000` cannot register passkeys because WebAuthn requires HTTPS or localhost. - The UI now explains the secure-origin requirement instead of saying the browser does not support passkeys. Current gate: waiting for explicit human merge approval.
erik 2026-06-04 15:09:24 -05:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
erik/slugkit#53
No description provided.