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:

    1. Direct OAuth calls from vitto-api (simpler but violates token isolation)
    1. Proxy through backend-api via existing oauthProxy() (maintains S234 security invariant)
    1. 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


🔗 Related


Auto-generated by MCP Smart Consolidation