Skip to content

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

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

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

Conversation

@mroderick

@mroderick mroderick commented Jun 18, 2026

Copy link
Copy Markdown
Collaborator

This adds an integration with our new auth app (auth.codebar.io), which allows users to sign up with a magic link as well as github.

Initially, this will not be available through the UI, but on a new url: https://codebar.io/auth/codebar instead of https://codebar.io/auth/github

This allows us to iron out any kinks there might be, before we start relying on it.

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.

@mroderick mroderick force-pushed the feature/magic-link-auth branch from e01eabc to 8ed635e Compare June 18, 2026 08:49
@mroderick mroderick force-pushed the feature/magic-link-auth branch 5 times, most recently from f6cbdde to 213613f Compare June 22, 2026 09:55
Add a custom OmniAuth strategy that connects the planner to the auth
service via OAuth 2.1 / OIDC.

- lib/omniauth/strategies/codebar.rb: the strategy implementation
  - request_phase: generates PKCE params and redirects to auth service
    authorize endpoint
  - callback_phase: exchanges code for tokens, verifies JWT via JWKS,
    builds omniauth.auth hash
  - Supports EdDSA, RS256, ES256 via JWT.decode with jwks: option
  - Caches JWKS for 15 minutes with cache-bust on kid mismatch
  - Uses email claim as uid, falls back to sub if email is missing

- config/initializers/omniauth.rb: registers the codebar provider
  with auth_url and audience from env vars

- spec/lib/omniauth/strategies/codebar_spec.rb: 13 tests covering
  request phase, callback error paths (CSRF, missing code/PKCE,
  exchange failure, invalid JWT), successful callback with JWT
  verification, and call! routing
@mroderick mroderick force-pushed the feature/magic-link-auth branch from 213613f to 7aca666 Compare June 22, 2026 10:50
@mroderick mroderick marked this pull request as ready for review June 22, 2026 11:31
@mroderick mroderick requested a review from olleolleolle June 22, 2026 11:33
@mroderick

Copy link
Copy Markdown
Collaborator Author

This is the related PR in auth: codebar/auth#32

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