Skip to content

feat(auth): native WebAuthn passkeys for panel login#4544

Draft
iyobo wants to merge 2 commits into
Dokploy:canaryfrom
iyobo:feat/native-passkeys
Draft

feat(auth): native WebAuthn passkeys for panel login#4544
iyobo wants to merge 2 commits into
Dokploy:canaryfrom
iyobo:feat/native-passkeys

Conversation

@iyobo
Copy link
Copy Markdown

@iyobo iyobo commented Jun 3, 2026

Summary

Adds WebAuthn passkeys (Touch ID, Face ID, Windows Hello, security keys) to Dokploy panel login and account settings, using Better Auth's @better-auth/passkey plugin at 1.5.4 (aligned with existing better-auth / @better-auth/* pins — no 1.6 upgrade).

Closes / implements the request in #1296 (passwordless / passkey sign-in).

What changed

  • Server: passkey() plugin in auth.ts, auth-cli.ts for schema generation, passkey-rp.ts for rpID / origin
  • DB: passkey table + Drizzle migration 0170_naive_stardust.sql
  • Login: "Sign in with passkey" on / (handles twoFactorRedirect like email login)
  • Profile: Manage passkeys — list, register, delete (manage-passkeys.tsx)

Self-hosted operators

Set BETTER_AUTH_URL (or NEXT_PUBLIC_APP_URL) to the exact HTTPS URL users open in the browser (no trailing slash), e.g. https://fleet.example.com. WebAuthn rpID/origin are resolved at server init from that URL. Without it, dev defaults to localhost; production may fall back to http://localhost:PORT which will break passkeys on a real hostname.

Cloud (IS_CLOUD) uses https://app.dokploy.com / app.dokploy.com automatically.

Test plan

  • Run pnpm migration:run in apps/dokploy on a dev/staging instance
  • Set BETTER_AUTH_URL to your public HTTPS Dokploy URL (self-hosted)
  • Sign in with email/password → Profile → Manage passkeys → add passkey (biometric prompt)
  • Sign out → Sign in with passkey → completes (or prompts TOTP if 2FA enabled)
  • With 2FA enabled: passkey sign-in still routes through existing TOTP UI when twoFactorRedirect is returned
  • Delete a passkey from profile; confirm removed credential cannot sign in

Security notes

  • Passkeys are origin-bound (phishing-resistant vs TOTP copy-paste)
  • Registration requires an authenticated session (default Better Auth behavior)
  • TOTP 2FA remains available as a parallel factor / fallback

Related

Made with Cursor

Co-authored-by: Cursor <cursoragent@cursor.com>
@iyobo iyobo requested a review from Siumauricio as a code owner June 3, 2026 23:35
@dosubot dosubot Bot added size:XL This PR changes 500-999 lines, ignoring generated files. enhancement New feature or request labels Jun 3, 2026
@iyobo iyobo marked this pull request as draft June 3, 2026 23:46
Resolve WebAuthn RP/origin from env or server settings, document self-hosted setup, add audit logs for passkey lifecycle, and polish login/profile UX with tests.

Co-authored-by: Cursor <cursoragent@cursor.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request size:XL This PR changes 500-999 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant