ADR-001: Third-Party API Exposure Strategy β Public API FaΓ§ade
Metadataβ
| Field | Value |
|---|---|
| Status | β Accepted |
| Date | 18 January 2026 |
| Linear | CAB-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β
| Problem | Impact | Severity |
|---|---|---|
| Cross dependencies | Each component directly accesses PostgreSQL, GitLab, Keycloak | π΄ High |
| Unclear webMethods role | Used for admin AND runtime, difficult to scale | π΄ High |
| Logic duplication | Validation, auth, tenant isolation repeated everywhere | π‘ Medium |
| Coupled deployment | Impossible 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β
| Option | Description | Verdict |
|---|---|---|
| A. Modular monolith | Everything in one artifact | β Against open-core, all-or-nothing scaling |
| B. Pure microservices | One service per domain | β Overkill for team size |
| C. Control Plane / Data Plane | Clear separation of responsibilities | β Selected |
Architectureβ
Componentsβ
| Component | Type | Role | Dependencies |
|---|---|---|---|
| STOA Core API | Backend (FastAPI) | Central hub, all business logic | PostgreSQL, GitLab, Keycloak |
| STOA Portal | Frontend (React) | Developer self-service | Core API only |
| STOA Console | Frontend (React) | Platform administration | Core API only |
| STOA MCP Server | Backend (Python) | AI/LLM interface | Core API only |
| webMethods Gateway | Data Plane | API runtime traffic execution | Config 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β
- Kubernetes Control Plane / Data Plane separation
- Istio Pilot (control) vs Envoy (data)
- Kong Konnect architecture
- ADR-012: MCP Tools Architecture