Skip to content

feat: add magic link auth provider with code exchange#2649

Draft
mroderick wants to merge 2 commits into
masterfrom
feature/magic-link-auth
Draft

feat: add magic link auth provider with code exchange#2649
mroderick wants to merge 2 commits into
masterfrom
feature/magic-link-auth

Conversation

@mroderick

Copy link
Copy Markdown
Collaborator

Summary

Adds a custom OmniAuth strategy (:codebar) that delegates authentication to a separate auth app running on port 3001. The auth app becomes an identity provider — users authenticate via magic link or GitHub OAuth on the auth app, which issues a one-time code exchanged server-to-server for a signed JWT.

Key Design Decisions

  • One-time code exchange over JWT in URL: JWT never appears in browser URL/history/logs. Delivered via opaque single-use code with 5-minute TTL.
  • RS256/ES256 via JWKS: No shared secret — planner verifies JWT signatures using auth app's public JWKS endpoint, whitelisted algorithms only.
  • State/nonce CSRF: Random nonce stored in Rails session, passed through auth app, verified on callback.
  • Phased coexistence: Both :github and :codebar providers coexist — existing auth controller unchanged.
  • JWKS cache: 15-minute TTL with automatic bust on unknown kid.

Files

  • lib/omniauth/strategies/codebar.rb — Custom OmniAuth strategy (request_phase, callback_phase, code exchange, JWT verification)
  • config/initializers/omniauth.rb — Added :codebar provider alongside existing :github
  • spec/lib/omniauth/strategies/codebar_spec.rb — 16 tests covering all error paths through callback phase
  • Gemfile / Gemfile.lock — Added jwt gem

Testing

484 examples, 0 failures. All existing auth service tests continue to pass. New strategy tests cover state mismatch, missing code, empty code, exchange failure, JWT verification failure, and full success path.

Adds a custom OmniAuth provider that delegates authentication to a
separate auth app. The auth callback receives a one-time code which is
exchanged server-to-server for a JWT, verified against the auth app's
JWKS endpoint. State/nonce protects against CSRF; only RS256/ES256
algorithms are accepted.
@mroderick mroderick force-pushed the feature/magic-link-auth branch from e01eabc to 8ed635e Compare June 18, 2026 08:49
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