Skip to content

Implement Better Auth email OTP and registration policy - #1

Draft
totally-tim wants to merge 159 commits into
mainfrom
agent/better-auth-email-otp
Draft

totally-tim wants to merge 159 commits into
mainfrom
agent/better-auth-email-otp

Conversation

@totally-tim

Copy link
Copy Markdown
Contributor

What changed

  • replace the bespoke browser and device authentication boundary with embedded Better Auth sessions, passkeys, and RFC 8628 device authorization
  • add passwordless six-digit email OTP delivery through Resend
  • add closed, invitation-only, and allowlist registration modes with exact email/domain allow and deny rules
  • keep verified email separate from Collab membership and prohibit email-based identity merging
  • add authenticated email enrollment for existing members and preserve passkeys for privileged actions
  • harden OTP rate limits, concurrent attempt counting, resend ordering, offboarding, restore, and raw Better Auth endpoint exposure
  • add schema migrations 17 and 18, deployment authority initialization, backup portability fixes, UI flows, and adversarial coverage

Why

The previous custom authentication flow made routine sign-in, runner pairing, and long-term maintenance unnecessarily fragile. This adopts a maintained OSS authentication core while retaining Collab's explicit membership and execution-authority boundaries.

User impact

Members can sign in with a passkey or an emailed one-time code. Owners can close registration, require invitations, or allow specific addresses and domains with deny precedence. Existing identities are never merged merely because email strings match.

Root causes fixed

  • custom session and pairing behavior diverged across browser and CLI paths
  • OTP attempts and resend delivery required Collab-owned serialization around Better Auth
  • the production bundle omitted a dynamically imported OpenTelemetry peer and crashed on a read-only filesystem
  • bootstrap omitted deployment authority state, preventing authenticated backups
  • Bun SQLite in-memory deserialization was not portable to the Linux runtime

Verification

  • bun ci
  • bun run format:check
  • bun run lint
  • bun run typecheck
  • bun run test — 793 passed
  • bun run build
  • bunx playwright install chromium
  • bun run test:e2e:run — 23 passed, 27 explicitly skipped live-provider evidence cases
  • bun run audit:public
  • bun run manifest:verify
  • docker compose config --quiet
  • docker build --tag 2collab:email-otp-final .
  • live hardened Mac Studio deployment, schema 18, authenticated backup, Tailnet health, device-code issuance, and Resend provider smoke

# Conflicts:
#	src/server/dependencies.ts
# Conflicts:
#	src/cli/command.ts
#	src/runner/production.ts
#	tests/unit/cli/runner-command.test.ts
@socket-security

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Addedyaml@​2.9.010010010084100
Addedbetter-auth@​1.6.23981008596100
Added@​opentelemetry/​api@​1.9.110010010086100
Added@​better-auth/​passkey@​1.6.231001008797100
Added@​simplewebauthn/​server@​13.3.2981008891100
Added@​modelcontextprotocol/​sdk@​1.29.09910010092100

View full report

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant