Unclassified
Round 2 — Auth Node Inventory
Date: 2026-07-29
Status: Code exists; production keys needed
Current Auth Architecture
What Exists in Code
| Module | Location | Status |
|---|---|---|
| Clerk JWT verification | services/gateway/src/clerk-auth.ts | ✅ Implemented |
| Clerk principal mapping | services/gateway/src/clerk-auth.ts → mapClerkPrincipal() | ✅ Implemented |
| Customer Zero detection | packages/types/src/customer-zero.ts → isCustomerZeroEmail() | ✅ Implemented |
| Descope adapter (legacy) | services/gateway/src/descope-auth.ts | ⚠️ Legacy, still in codebase |
| OAuth authorization server | services/mcp-connector/src/lib/oauth-auth-server.ts | ✅ Implemented |
| OAuth scope enforcement | services/mcp-connector/src/lib/oauth-scopes.ts | ✅ Implemented |
| Gateway auth middleware | services/gateway/src/index.ts:1928-1970 | ✅ Implemented |
| MCP Connector auth | services/mcp-connector/src/lib/access-auth.ts | ✅ Implemented |
Auth Flow (Current)
Client → Gateway
→ Bearer token extracted
→ Try Clerk verification (primary)
→ verifyClerkToken(bearerToken, clerkSecretKey)
→ mapClerkPrincipal(clerkPrincipal, { surface })
→ VerifiedPrincipal: { userId, email, roles, tenantId, surface }
→ If Clerk fails → Try Descope (legacy fallback)
→ If both fail → 401
→ Tenant resolution from VerifiedPrincipal.tenantId
→ Trusted headers overwritten by Gateway
→ Forward to downstream service
VerifiedPrincipal Shape
interface VerifiedPrincipal {
userId: string;
email?: string;
name?: string;
roles: readonly string[];
tenantId: string;
organizationId?: string;
surface: "integratewise-web" | "integratewise-api" | "iw-mcp";
isAgent?: boolean;
agentId?: string;
delegationRef?: string;
issuedAt?: number;
expiresAt?: number;
}
Surface Mapping
| Surface | Trigger | Used by |
|---|---|---|
integratewise-web | Frontend browser session | Gateway → all services |
integratewise-api | External API client | Gateway → MCP Connector |
iw-mcp | MCP client (Cursor, ChatGPT, etc.) | Gateway → MCP Connector |
Single Shared Auth Node: What Needs to Happen
P0 #10 Requirements
The single shared auth node must handle:
- Identity: Clerk JWT verification →
VerifiedPrincipal - Authorization: OAuth scope enforcement → tool-level access control
- Tenant resolution:
VerifiedPrincipal.tenantId→ all downstream services - Workspace resolution: Clerk org_id → workspace projections
- Marketplace installation identity: Installation JWT → tenant + scopes
What's Missing
| Item | Status | Action |
|---|---|---|
| Clerk production secret key | ❌ Not in .env | Set CLERK_SECRET_KEY in Cloudflare Workers secrets |
| Clerk publishable key | ❌ Not in .env | Set NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY in Pages environment |
| Clerk JWKS endpoint | ✅ Hardcoded in clerk-auth.ts | Verify it resolves after DNS is live |
| Descope removal | ⚠️ Legacy code still present | Remove descope-auth.ts after Clerk is verified in production |
GATEWAY_CONNECTOR_AUTH_SECRET | ❌ Not set | Generate shared secret for Gateway→MCP Connector auth |
OAUTH_PRIVATE_KEY | ❌ Not set | Generate RSA keypair for OAuth JWT signing |
| Tenant resolution middleware | ✅ Exists in Gateway | Verify it works with real Clerk org data |
| Installation identity | ⚠️ Partial | Marketplace installation JWT verification needs real verification |
Code Changes Needed
- Remove Descope fallback after Clerk production verification
- Add tenant resolution middleware that works with Clerk org_id
- Wire
GATEWAY_CONNECTOR_AUTH_SECRETfor Gateway→MCP Connector auth - Add OAuth keypair generation for production JWT signing
Production Clerk Setup Checklist
- Create Clerk application at dashboard.clerk.com
- Configure social connections (Google, GitHub, email)
- Create organizations feature
- Create
iw-customer-zeroorganization - Add
@integratewise.aidomain to organization - Generate production API keys:
- Secret key →
CLERK_SECRET_KEY(Cloudflare Workers secret) - Publishable key →
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY(Pages env)
- Secret key →
- Configure JWT templates if needed (org_id, org_role, tenant_id)
- Verify JWKS endpoint:
https://integratewise.ai/clerk/.well-known/jwks.json
Verification
After production Clerk is configured:
# Test Clerk JWT verification
curl -H "Authorization: Bearer <valid-clerk-jwt>" \
https://gateway.integratewise.ai/api/v1/workspace/discovery
# Expected: 200 with WorkspaceDiscoveryResponse
# If 401: Clerk keys not configured or JWT invalid