Repository navigation
feat: implement BYOK AI key resolution and rate limits - #383
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Warning Review limit reached
Next review available in: 42 minutes You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (3)
📝 WalkthroughWalkthroughThe PR adds user and project BYOK endpoints, encrypted key storage, AES-256-GCM transit protection, Python-side key resolution, Redis-backed plan limits, and AI request forwarding. ChangesBYOK AI flow
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant DashboardAPI
participant PythonAIService
participant TransitCrypto
participant Redis
participant Groq
DashboardAPI->>PythonAIService: Send developer ID, plan, and encrypted Groq key
PythonAIService->>TransitCrypto: Decrypt transit payload
TransitCrypto-->>PythonAIService: Return Groq API key
PythonAIService->>Redis: Check platform usage counter
Redis-->>PythonAIService: Return counter state
PythonAIService->>Groq: Create ChatGroq client and execute query
Groq-->>PythonAIService: Return structured result
Possibly related PRs
Suggested labels: Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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 |
There was a problem hiding this comment.
Actionable comments posted: 3
🧹 Nitpick comments (1)
apps/python-service/tests/test_byok.py (1)
77-77: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winResolve the reported unused-unpack warnings.
Replace unused mock values with
_. This keeps the test file clean under the configured Ruff checks.Proposed fix
- mock_rc, mock_pipe = mock_redis + _, mock_pipe = mock_redis ... - mock_rc, mock_pipe = mock_redis + _, mock_pipe = mock_redis ... - mock_rc, mock_pipe = mock_redis + mock_rc, _ = mock_redisAlso applies to: 94-94, 105-105
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@apps/python-service/tests/test_byok.py` at line 77, Update the mock unpacking assignments in the affected tests to bind unused values to _ instead of mock_rc or mock_pipe, including the assignments around mock_redis at all referenced locations, while preserving the values that each test uses.Source: Linters/SAST tools
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@apps/dashboard-api/src/__tests__/routes.user.test.js`:
- Line 43: Update the updateByok mock response in the route test to include the
required message field alongside success and data, using an empty string
consistent with the API response contract.
In `@apps/dashboard-api/src/controllers/auth.controller.js`:
- Around line 705-707: Normalize unexpected BYOK errors in the catch blocks at
apps/dashboard-api/src/controllers/auth.controller.js:705-707 and
apps/dashboard-api/src/controllers/project.controller.js:3482-3483 by forwarding
existing AppError instances unchanged and wrapping every other error in a
generic AppError before calling next, preventing database or encryption details
from reaching response middleware.
In `@apps/python-service/services/byok.py`:
- Line 64: Require a stable developer identity before resolving platform keys:
in apps/python-service/services/byok.py lines 64-64, reject platform-key
requests without developer_id, then apply the free-tier limit whenever plan !=
"pro"; in apps/python-service/routers/ai.py lines 35-37, require developer_id
for non-BYOK requests or add model validation rejecting requests with neither
BYOK credentials nor a developer identity.
---
Nitpick comments:
In `@apps/python-service/tests/test_byok.py`:
- Line 77: Update the mock unpacking assignments in the affected tests to bind
unused values to _ instead of mock_rc or mock_pipe, including the assignments
around mock_redis at all referenced locations, while preserving the values that
each test uses.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 19a88815-eb7f-4b48-b0a5-0fd382edab83
📒 Files selected for processing (19)
apps/dashboard-api/src/__tests__/routes.projects.storage.test.jsapps/dashboard-api/src/__tests__/routes.user.test.jsapps/dashboard-api/src/controllers/ai.controller.jsapps/dashboard-api/src/controllers/auth.controller.jsapps/dashboard-api/src/controllers/project.controller.jsapps/dashboard-api/src/routes/projects.jsapps/dashboard-api/src/routes/user.jsapps/dashboard-api/src/utils/transitEncryption.jsapps/python-service/.env.exampleapps/python-service/config.pyapps/python-service/requirements.txtapps/python-service/routers/ai.pyapps/python-service/services/__init__.pyapps/python-service/services/byok.pyapps/python-service/services/transit_crypto.pyapps/python-service/tests/test_auth.pyapps/python-service/tests/test_byok.pypackages/common/src/models/Developer.jspackages/common/src/models/Project.js
There was a problem hiding this comment.
Pull request overview
Adds Bring-Your-Own-Key (BYOK) support for Groq-backed AI features across the dashboard API and Python AI service, including hierarchical key resolution (project → developer → platform) and free-tier generation rate limiting, with a new AES-256-GCM “transit encryption” layer for safely passing decrypted keys to the Python service.
Changes:
- Introduces
byok.groqKeystorage on bothProjectandDevelopermodels (encrypted at rest), with new dashboard endpoints to save/clear keys. - Adds Python-side BYOK resolution (
resolve_ai_client) and free-tier monthly generation limiting via Redis; updates the AI router to use this resolver. - Implements Node→Python transit encryption/decryption (AES-256-GCM) and adds tests + documentation/env example updates.
Reviewed changes
Copilot reviewed 19 out of 19 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/common/src/models/Project.js | Adds project-level BYOK field for Groq key. |
| packages/common/src/models/Developer.js | Adds developer-level BYOK field for Groq key (encrypted at rest). |
| apps/python-service/tests/test_byok.py | Adds tests for BYOK decryption, fallback behavior, and rate limiting. |
| apps/python-service/tests/test_auth.py | Updates env setup for new required/used config fields. |
| apps/python-service/services/transit_crypto.py | Adds AES-256-GCM decryption compatible with Node transit encryption. |
| apps/python-service/services/byok.py | Adds key resolution + free-tier rate limiting logic. |
| apps/python-service/services/init.py | Introduces services package marker. |
| apps/python-service/routers/ai.py | Adds request fields for plan/BYOK payload and uses resolver. |
| apps/python-service/requirements.txt | Adds pycryptodome for AES-GCM operations. |
| apps/python-service/config.py | Adds INTERNAL_PAYLOAD_KEY setting for transit decryption. |
| apps/python-service/.env.example | Documents INTERNAL_PAYLOAD_KEY usage and requirement. |
| apps/dashboard-api/src/utils/transitEncryption.js | Adds Node-side AES-256-GCM transit encryption helper. |
| apps/dashboard-api/src/routes/user.js | Adds developer BYOK update endpoint. |
| apps/dashboard-api/src/routes/projects.js | Adds project BYOK update endpoint. |
| apps/dashboard-api/src/controllers/project.controller.js | Implements project BYOK save/clear controller. |
| apps/dashboard-api/src/controllers/auth.controller.js | Implements developer BYOK save/clear controller. |
| apps/dashboard-api/src/controllers/ai.controller.js | Resolves project/developer key, encrypts for transit, forwards to Python. |
| apps/dashboard-api/src/tests/routes.user.test.js | Mocks new user BYOK controller route. |
| apps/dashboard-api/src/tests/routes.projects.storage.test.js | Mocks new project BYOK controller route. |
Suppressed comments (1)
apps/dashboard-api/src/controllers/ai.controller.js:82
- This developer BYOK lookup is read-only; adding
.lean()avoids Mongoose document hydration overhead.
const dev = await Developer.findById(req.user._id).select('+byok');
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@apps/dashboard-api/src/controllers/ai.controller.js`:
- Around line 82-84: Update the project lookup in the controller around
Project.findById so it applies getProjectAccessQuery(req.user._id) before
selecting the encrypted BYOK fields. Preserve the existing lean result and
ensure the BYOK key is only loaded when the current user still has project
access.
In `@apps/python-service/services/byok.py`:
- Around line 75-83: Update the counter logic around the Redis pipeline in the
enclosing usage-tracking function to atomically increment the key and assign the
initial 32-day TTL in the same Redis operation, using a Lua script or equivalent
atomic command, and return the resulting count. Remove the separate
post-execution expire path, while preserving existing TTL behavior for
already-expiring counters. Add a test covering first use and verifying the TTL
is set.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 37f28911-a2b4-417e-8ce6-a5e3f668eb18
📒 Files selected for processing (8)
apps/dashboard-api/src/__tests__/routes.user.test.jsapps/dashboard-api/src/controllers/ai.controller.jsapps/dashboard-api/src/controllers/auth.controller.jsapps/dashboard-api/src/controllers/project.controller.jsapps/python-service/config.pyapps/python-service/routers/ai.pyapps/python-service/services/byok.pyapps/python-service/tests/test_byok.py
🚧 Files skipped from review as they are similar to previous changes (3)
- apps/dashboard-api/src/tests/routes.user.test.js
- apps/python-service/config.py
- apps/python-service/routers/ai.py
BYOK-GROK-AI KEY
Summary by CodeRabbit
New Features
Documentation
Tests