Aller au contenu principal

ADR-001: Third-Party API Exposure Strategy — Public API Façade

Metadata

FieldValue
Status✅ Accepted
Date18 January 2026
LinearCAB-669 (Epic)

Context

STOA Platform evolves with several components in parallel: Control-Plane API (FastAPI), MCP Gateway, Developer Portal (React), Console (React), and webMethods Gateway.

Identified Problems

ProblemImpactSeverity
Cross dependenciesEach component directly accesses PostgreSQL, GitLab, Keycloak🔴 High
Unclear webMethods roleUsed for admin AND runtime, difficult to scale🔴 High
Logic duplicationValidation, auth, tenant isolation repeated everywhere🟡 Medium
Coupled deploymentImpossible to deploy Portal without MCP Gateway🟡 Medium

Architectural Question

How to structure STOA components so they are independently deployable, while maintaining GitLab as source of truth and clarifying each element's role?

Decision

Adopt a Control Plane / Data Plane architecture with Core API as central hub.

Options Considered

OptionDescriptionVerdict
A. Modular monolithEverything in one artifact❌ Against open-core, all-or-nothing scaling
B. Pure microservicesOne service per domain❌ Overkill for team size
C. Control Plane / Data PlaneClear separation of responsibilitiesSelected

Architecture

Components

ComponentTypeRoleDependencies
STOA Core APIBackend (FastAPI)Central hub, all business logicPostgreSQL, GitLab, Keycloak
STOA PortalFrontend (React)Developer self-serviceCore API only
STOA ConsoleFrontend (React)Platform administrationCore API only
STOA MCP ServerBackend (Python)AI/LLM interfaceCore API only
webMethods GatewayData PlaneAPI runtime traffic executionConfig sync from Core API

Architecture Rules

Rule 1: Unidirectional Dependencies

Forbidden: Portal → PostgreSQL (direct), MCP Server → GitLab (direct)

Rule 2: GitLab = Source of Truth for Definitions

# What lives in GitLab (stoa-catalog)
stoa-catalog/
tenants/{tenant}/
apis/{api}/
api.yaml # API definition
openapi.yaml # OpenAPI spec

# What lives in PostgreSQL
- subscriptions, api_keys, audit_logs, rate_limit_usage, mcp_sessions

Rule 3: webMethods = Data Plane Only

DO: Routing, Rate limiting, JWT validation, Transformation, Caching ❌ DON'T: Serve UIs, Manage subscriptions, Store data

Public API Façade

Architecture

Endpoints Exposed to Third Parties

/v1/portal/:
catalog: # Public or API key
GET /apis, GET /apis/{id}, GET /apis/{id}/spec
subscriptions: # OAuth2 required
GET/POST/DELETE /subscriptions
me: # OAuth2 required
GET /me, GET /me/usage

NEVER exposed: /v1/admin/*, /v1/tenants/*/members, /v1/gateway/*

Consequences

Positive

  • ✅ Independent component deployment
  • ✅ GitLab remains source of truth
  • ✅ Clear Control Plane / Data Plane separation
  • ✅ Secure third-party exposure

Negative

  • ⚠️ Additional latency (MCP → Core API vs direct DB)
  • ⚠️ Migration effort

References