Bind MCP grants to stable account identity - #840
Conversation
📝 WalkthroughWalkthroughEmail verification and MCP authentication now use deterministic ChangesStable identity authentication
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant GrantProps
participant MCPContext
participant APP_DB
participant PermissionsDB
GrantProps->>MCPContext: Provide stable user ID
MCPContext->>APP_DB: Load user by stable_user_id
APP_DB-->>MCPContext: Return profile row
MCPContext->>PermissionsDB: Load roles and permissions
PermissionsDB-->>MCPContext: Return authorization data
MCPContext-->>GrantProps: Return enriched user context
Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 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 |
e79f794 to
f960a9b
Compare
f960a9b to
c3ee1c9
Compare
|
🔎 Preview deployed: https://kody-pr-840.kody-a99.workers.dev Worker: Mocks:
|
There was a problem hiding this comment.
🧹 Nitpick comments (1)
packages/worker/src/mcp-auth-user-context.ts (1)
27-28: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueFallback email isn't normalized like the DB-refreshed path.
buildBaseUserFromGrantonly trimsgrantProps.email, while the successful lookup path lowercases it (row.email.trim().toLowerCase(), line 80). Low risk since the fallback carries no roles, but worth aligning for consistency.♻️ Normalize email casing in the fallback path
const email = - typeof grantProps.email === 'string' ? grantProps.email.trim() : '' + typeof grantProps.email === 'string' + ? grantProps.email.trim().toLowerCase() + : ''🤖 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 `@packages/worker/src/mcp-auth-user-context.ts` around lines 27 - 28, Update buildBaseUserFromGrant’s fallback email normalization to trim and lowercase grantProps.email, matching the row.email normalization used by the successful lookup path while preserving the existing empty-string fallback.
🤖 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.
Nitpick comments:
In `@packages/worker/src/mcp-auth-user-context.ts`:
- Around line 27-28: Update buildBaseUserFromGrant’s fallback email
normalization to trim and lowercase grantProps.email, matching the row.email
normalization used by the successful lookup path while preserving the existing
empty-string fallback.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 28e04bcc-efc9-4109-9fce-8f4b46b53fca
📒 Files selected for processing (10)
packages/worker/src/app/email-verification.node.test.tspackages/worker/src/app/email-verification.tspackages/worker/src/email/inbound.workers.test.tspackages/worker/src/email/outbound.workers.test.tspackages/worker/src/entitlements/test-schema.tspackages/worker/src/mcp-auth-user-context.node.test.tspackages/worker/src/mcp-auth-user-context.tspackages/worker/src/mcp-auth.workers.test.tspackages/worker/src/mcp/capabilities/email/email-usage-get.workers.test.tspackages/worker/src/oauth-handlers.workers.test.ts
Summary
users.stable_user_id, not potentially stale grant emailWhy
After an account email change, an old grant email can later belong to another account. Email-only verification or role lookup could then combine one account's stable data identity with another account's verification/RBAC state.
Validation
npm run validate: passed on final rebased headSystem recap — extends existing primitives (medium risk)
Mode: recap · Base:
main@0b824ebc· Head:c3ee1c9bClassification: extends — tightens identity binding across MCP auth, email verification, and RBAC.
Primitives touched
app-sessionsemailentitlementsapp-uiSystem map
OAuth grant authentication resolves stable identity in D1 before attaching current account metadata or RBAC; verification checks bind both identity attributes.
Legend: green = composes (wiring only) · amber = extended by this PR · red = new primitive · gray = context (unchanged, included only when an edge crosses it).
Invariants
userIdremains the authoritative per-user data scope.Summary by CodeRabbit
Bug Fixes
Tests