Architecture: Where should OAuth API calls be executed — in vitto-api dire...
Documentation for Sessions
🏗️ Architecture: Where should OAuth API calls be executed — in vitto-api dire...
Date: 2026-03-31
Time: 19:06:08 UTC
Session: gspace1-290.25
Agent: backend
Confidence: 97%
Status: ✅ Documented
📋 Decision Context
Question:
Where should OAuth API calls be executed — in vitto-api directly or proxied through backend-api?
Task: S289: OAuth-First Intelligent Task Execution
🎯 Decision Made
Chosen:
ALL OAuth API calls proxy through BackendApiClientService.oauthProxy() → backend-api POST /auth/oauth/proxy. Tokens NEVER enter vitto-api or LLM context. Gmail executor calls backendApi.oauthProxy(userId, 'google', method, endpoint, body) — backend-api decrypts token, refreshes if expired, calls Gmail API, returns clean data.
Options Considered:
- Direct OAuth calls from vitto-api (simpler but violates token isolation)
- Proxy through backend-api via existing oauthProxy() (maintains S234 security invariant)
- Dedicated OAuth microservice (over-engineered for current scale)
💭 Reasoning
This follows the S234 architecture decision: backend-api (:3000) owns ALL OAuth tokens. vitto-api (:3003) is the orchestration layer that coordinates AI agents — it should NEVER hold credentials. If tokens were in vitto-api, they could leak into LLM context through agent loop prompts, debug logs, or SSE events. The proxy pattern also means vitto-api doesn't need the OAUTH_ENCRYPTION_KEY, reducing the blast radius of a vitto-api compromise. The existing BackendApiClientService already had oauthProxy() and getOAuthConnections() methods (added in S234), so zero new plumbing was needed on the proxy side.
📁 Files Involved
APIs/backend-vitto-api/src/app/engine/api-executors/gmail-api.executor.tsAPIs/backend-vitto-api/src/app/connectivity/backend-api-client.service.tsAPIs/backend-api/src/app/auth/oauth/oauth.service.ts
🔗 Related
- Decision ID:
dev_1774983968265_0ay163t - Session: 290
- Workspace: gspace1
Auto-generated by MCP Smart Consolidation