v2.3.0: Pingora Engine, Chat Settings, Zero-Config Bootstrap
Pingora's battle-tested connection engine meets AI-native API management β plus zero-config bootstrap, per-tenant chat controls, and real-data demo APIs.
Highlightsβ
Pingora Connection Engine (ADR-058)β
STOA Gateway now embeds Pingora, Cloudflare's proxy framework handling 1T+ requests/day. Rather than a full migration (55+ pts), we chose the embedded connector approach (13 pts): Pingora's shared connection pool lives inside the existing axum binary behind a pingora feature flag.
- Shared connection pool β designed for 1T+ req/day, replaces per-client reqwest pools at scale
- Zero architecture change β same binary, same routing, same API surface
- Feature-gated β
FEATURES=kafka,pingorain production builds (cmake required) - Future-proof β
ProxyPhasetrait maps 1:1 to Pingora'sProxyHttpfor a potential full migration at v2.0
Marketing claim: "STOA Gateway β powered by Pingora's connection engine"
See ADR-058 for the full decision record.
Per-Tenant Chat Settings & Source Trackingβ
Admins can now independently control the AI chat assistant in Console and Portal, with per-app usage tracking.
- Per-tenant toggles β enable/disable chat separately for Console and Portal
- Daily token budget β set spending limits per tenant to prevent runaway costs
- Source tracking β every chat message tagged with
X-Chat-Sourceheader (console or portal) - Usage breakdown β
GET /v1/chat/usage?group_by=sourceshows per-app token consumption - RBAC enforced β only
cpi-adminandtenant-admincan modify settings;viewergets 403 - 25 E2E scenarios β CRUD, RBAC, source header enforcement, cross-app integration
New endpoints:
| Method | Path | Description |
|---|---|---|
GET | /v1/chat/settings | Read tenant chat configuration |
PUT | /v1/chat/settings | Update chat toggles and budget |
Zero-Config Helm Bootstrapβ
First-time installations are now fully automated. A single helm install with bootstrap enabled provisions the entire platform:
- Keycloak realm β creates realm with registration enabled
- 4 RBAC roles β
cpi-admin,tenant-admin,devops,viewer - 3 client scopes β
stoa:read,stoa:write,stoa:admin - 4 OIDC clients β Console, Portal, Gateway, API (all pre-configured)
- Admin user β created with
cpi-adminrole ifadminEmailis set - Default tenant β provisioned via Control Plane API
helm install stoa-platform ./charts/stoa-platform \
--set stoa.bootstrap.enabled=true \
--set stoa.domain=example.com \
--set stoa.adminEmail=admin@example.com
The bootstrap job is idempotent β running it twice is safe (409 = already exists = OK).
Shared Secrets Managementβ
Internal service-to-service keys are now auto-generated and stable across upgrades:
| Key | Purpose |
|---|---|
gateway-consumer-key | Gateway β API authentication |
chat-internal-key | Chat service internal calls |
jwt-signing-key | JWT token signing |
anthropic-api-key | Anthropic API (optional) |
Keys persist across helm upgrade via Helm lookup function. When Anthropic API key is not provided, chat gracefully disables via CHAT_KILL_SWITCH.
Real-Data Demo APIsβ
The developer portal now ships with 5 real public APIs pre-configured for immediate testing:
| API | Auth | Rate Limit | Use Case |
|---|---|---|---|
| Exchange Rate API | None | Unlimited | Foreign exchange rates (180+ currencies) |
| CoinGecko | None | 30 req/min | Cryptocurrency prices and market cap |
| OpenWeatherMap | API Key | 1,000/day | Real-time weather data |
| NewsAPI | API Key | 100/day | Top headlines from 80+ sources |
| Alpha Vantage | API Key | 5/min | Stock prices and technical indicators |
Plus an echo backend fallback for when external APIs are unreachable β demos never break.
Gateway (Rust)β
| Capability | Description |
|---|---|
| Pingora Engine | Embedded shared connection pool behind pingora feature flag |
| OAuth Hairpin Fix | Internal Keycloak URL for DCR/token proxy β fixes 502 on K8s clusters |
| Deployment Mode Tracing | stoa.deployment_mode span attribute for Tempo service graph |
| Chat Source Header | X-Chat-Source propagation and enforcement |
OAuth Hairpin NAT Fixβ
OAuth proxy endpoints (token, DCR, PAR) were using the external Keycloak URL. On K8s clusters with hairpin NAT issues (e.g., OVH MKS), this caused 502 errors at the DCR registration step β breaking Claude.ai MCP connections.
Fix: New Config::keycloak_backend_url() prefers STOA_KEYCLOAK_INTERNAL_URL (K8s service DNS) for backend calls while keeping the external URL for browser-facing discovery fields.
Control Plane API (Python/FastAPI)β
| Capability | Description |
|---|---|
| Chat Settings | GET/PUT /v1/chat/settings β per-tenant toggles + budget |
| Source Tracking | ChatSource enum, X-Chat-Source header, group_by=source |
| API Seeding | Alembic migration 074 β 5 real APIs + echo fallback |
| Chat Budget | Per-tenant daily token limits with enforcement |
Console & Portal (React/TypeScript)β
- Chat Settings page β toggle chat per-app, set daily budget, save flow
- Source header injection β
useChatServicehook sendsX-Chat-Sourceon all requests - RBAC gates β viewer role blocked from settings modification
Helm Chartβ
New values:
| Key | Default | Description |
|---|---|---|
stoa.domain | β | Base domain for all services |
stoa.adminEmail | β | Admin user email (bootstrap) |
stoa.anthropicApiKey | β | Anthropic API key (optional, enables chat) |
stoa.bootstrap.enabled | false | Enable first-time platform provisioning |
Bug Fixesβ
- Portal 502 β Corrected
API_BACKEND_URLand addedDNS_RESOLVERin deployment manifest (#1813) - OAuth DCR 502 β Gateway now uses internal Keycloak URL for backend proxy calls (#1814)
- Tempo service graph β Deployment mode as span attribute (not resource attribute) for correct extraction (#1811)
Breaking Changesβ
None. All changes are backwards compatible.
Upgrade Guideβ
# Standard Helm upgrade (no bootstrap)
helm upgrade stoa-platform ./charts/stoa-platform -n stoa-system
# First-time install with bootstrap
helm install stoa-platform ./charts/stoa-platform -n stoa-system \
--set stoa.bootstrap.enabled=true \
--set stoa.domain=yourdomain.com \
--set stoa.adminEmail=admin@yourdomain.com
Gateway Docker images now require cmake at build time (Pingora dependency). Pre-built images from GHCR include this β no action needed for standard deployments.
What's Nextβ
- eBPF kernel-level HTTP parsing β zero-copy request inspection (CAB-1841/1843)
- UAC policy enforcement at kernel level β eBPF-based policy evaluation (CAB-1848)
- WASM plugin runtime β user-defined plugins in WebAssembly (CAB-1644)
- MCP Federation β cross-gateway tool discovery (ADR-046)
See the full roadmap for planned features and milestones.