feat: implement WorkOS Radar on auth actions
What does this PR do?
Adds WorkOS Radar integration for authentication fraud detection with comprehensive testing.
Change Summary
1. WorkOS Radar Integration
- New checkRadar() private method that checks user activity against WorkOS Radar API
- Integrated into signUpViaEmail() and signInViaEmail() flows
- Returns allow, block, or challenge actions
- Graceful fallback: allows authentication if Radar API fails
- Captures IP address and user agent for fraud detection
2. Request Metadata Extraction
- New getRequestMetadata() helper function
- Extracts IP address from x-forwarded-for or x-real-ip headers
- Captures user agent for Radar analysis
- Automatically passed to signup/signin flows
3. Base Provider Updates
- Updated signUpViaEmail and signInViaEmail interfaces
- Added optional ipAddress and userAgent parameters
4. Comprehensive Test Suite
- 8 passing tests covering: -- Signup with block/allow/challenge Radar responses -- Signin with Radar checks -- API failure scenarios -- Network error handling
5. Reusable Mock Infrastructure
- Environment configuration mocks
- WorkOS SDK mock factory
- Test utilities (fetch mocks, Radar helpers)
- README for complete usage documentation
Fixes #4340
Type of change
- [ ] Bug fix (non-breaking change which fixes an issue)
- [ ] Chore (refactoring code, technical debt, workflow improvements)
- [ ] Enhancement (small improvements)
- [x] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
- [ ] This change requires a documentation update
How should this be tested?
- Automated Testing
- New Vitest tests added, with mocks
- Manual Testing
- Pretend to be a bot: https://github.com/mcstepp/unkey-playwright
Checklist
Required
- [x] Filled out the "How to test" section in this PR
- [x] Read Contributing Guide
- [x] Self-reviewed my own code
- [x] Commented on my code in hard-to-understand areas
- [x] Ran
pnpm build - [x] Ran
pnpm fmt - [ ] Ran
make fmton/godirectory - [x] Checked for warnings, there are none
- [x] Removed all
console.logs - [x] Merged the latest changes from main onto my branch with
git pull origin main - [x] My changes don't cause any responsiveness issues
Appreciated
- [ ] If a UI change was made: Added a screen recording or screenshots to this PR
- [ ] Updated the Unkey Docs if changes were necessary
โ ๏ธ No Changeset found
Latest commit: edc700ff2a3df655f47413b12493dbb7a1249bab
Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.
This PR includes no changesets
When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types
Click here to learn what changesets are, and how to add one.
Click here if you're a maintainer who wants to add a changeset to this PR
The latest updates on your projects. Learn more about Vercel for GitHub.
๐ Walkthrough
Walkthrough
Adds request-metadata extraction (IP and user agent) in server auth actions; updates provider method signatures to accept metadata; integrates WorkOS Radar pre-checks into sign-up/sign-in flows (blocks on Radar "block"); and adds tests, mocks, and documentation for Radar-related behavior.
Changes
| Cohort / File(s) | Summary |
|---|---|
Auth action metadata apps/dashboard/app/auth/actions.ts |
Extracts ipAddress and userAgent from request headers and augments sign-up/sign-in payloads with that metadata before calling the auth layer. |
Provider signatures & local impl apps/dashboard/lib/auth/base-provider.ts, apps/dashboard/lib/auth/local.ts |
Updated signInViaEmail and signUpViaEmail signatures to accept optional { ipAddress?: string; userAgent?: string }; local provider updated to accept new parameter shapes (behavior unchanged). |
WorkOS provider + Radar apps/dashboard/lib/auth/workos.ts, apps/dashboard/lib/auth/types.ts |
Adds Decision type and exported WORKOS_RADAR_API_URL; introduces private checkRadar() which POSTs to Radar with email, ip_address, user_agent, auth_method, and action; signUpViaEmail and signInViaEmail perform Radar pre-checks and throw RADAR_BLOCKED on action === "block"; Radar failures default to allow; WorkOS client initialization now stores apiKey. |
Test mocks docs & helpers apps/dashboard/lib/auth/__mocks__/README.md, apps/dashboard/lib/auth/__mocks__/env.ts, apps/dashboard/lib/auth/__mocks__/setup.ts, apps/dashboard/lib/auth/__mocks__/workos.ts |
New test utilities and documentation: environment factories (mockWorkOSEnv, mockLocalEnv), test setup helpers (fetch/Radar mocks, response builders), WorkOS SDK mock factory (createMockWorkOSInstance), and README describing usage and extension guidelines. |
Radar tests apps/dashboard/lib/auth/tests/check-radar.test.ts |
New test suite validating Radar outcomes (block/allow/challenge, HTTP failure, network error) for sign-up and sign-in flows using the provided mocks. |
Sequence Diagram(s)
sequenceDiagram
participant Client
participant Action as Auth Action (server)
participant Provider as Auth Provider (WorkOS)
participant Radar as Radar API
participant WorkOS as WorkOS SDK
rect `#EEF6FF`
Note over Client,Action: Client calls signUp/signIn
end
Client->>Action: signUpViaEmail(userData) / signInViaEmail(email)
Action->>Action: extract ipAddress & userAgent from headers
Action->>Provider: call signUp/signIn with metadata
rect `#FFF7EF`
Note over Provider,Radar: Radar pre-check
end
Provider->>Radar: POST WORKOS_RADAR_API_URL { email?, ip_address?, user_agent?, auth_method:"Email_OTP", action:"sign-up"|"sign-in" }
Radar-->>Provider: { action: "allow" | "block" | "challenge", reason? }
alt action == "block"
Provider-->>Client: throw RADAR_BLOCKED
else action == "allow" || action == "challenge"
Provider->>WorkOS: proceed (create user / magic auth / list users)
WorkOS-->>Provider: success
Provider-->>Client: EmailAuthResult success
end
Estimated code review effort
๐ฏ 3 (Moderate) | โฑ๏ธ ~20โ30 minutes
- Areas to focus:
checkRadar()โ payload fields, HTTP error handling, and fallback-to-allow behavior.- Propagation of
ipAddressanduserAgentfromapps/dashboard/app/auth/actions.tsinto provider calls. - Ensure
action === "block"short-circuits before any WorkOS side effects. - Tests and mocks under
apps/dashboard/lib/auth/__mocks__/*andapps/dashboard/lib/auth/tests/check-radar.test.tsfor realistic Radar response simulation and isolation.
Pre-merge checks and finishing touches
โ Failed checks (1 warning, 2 inconclusive)
| Check name | Status | Explanation | Resolution |
|---|---|---|---|
| Docstring Coverage | โ ๏ธ Warning | Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. | You can run @coderabbitai generate docstrings to improve docstring coverage. |
| Linked Issues check | โ Inconclusive | The PR implements WorkOS Radar fraud detection but linked issue #4340 specifically requests rate limiting for magic code login. While Radar can inform rate limiting, the PR doesn't implement explicit rate-limiting logic. | Clarify whether this PR fulfills #4340's rate-limiting requirement or if additional rate-limiting implementation is needed beyond Radar integration. |
| Out of Scope Changes check | โ Inconclusive | The PR adds comprehensive Radar fraud detection infrastructure and test mocks that extend beyond the linked issue's rate-limiting scope. It's unclear if all infrastructure changes are necessary for the stated objective. | Confirm whether the extensive mock infrastructure and test utilities are all required for the rate-limiting objective or if some represent future-proofing. |
โ Passed checks (2 passed)
| Check name | Status | Explanation |
|---|---|---|
| Title check | โ Passed | The title accurately summarizes the main change: implementing WorkOS Radar integration for authentication, which is the core feature of this PR. |
| Description check | โ Passed | The description is comprehensive and well-structured, covering all key aspects: summary of changes, type of change marked, testing instructions provided, and most required checklist items completed. |
โจ Finishing touches
- [ ] ๐ Generate docstrings
๐งช Generate unit tests (beta)
- [ ] Create PR with unit tests
- [ ] Post copyable unit tests in a comment
- [ ] Commit unit tests in branch
ENG-2218-radar-for-auth
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.
Comment @coderabbitai help to get the list of available commands and usage tips.
Thank you for following the naming conventions for pull request titles! ๐
Graphite Automations
"Post a GIF when PR approved" took an action on this PR โข (11/20/25)
1 gif was posted to this PR based on Andreas Thomas's automation.