ADR-0008: The data gateway is the sole data path¶
Status: Accepted — 003-governance-depth (2026-07) Principles served: I, II, III Source: specs/003-governance-depth/research.md G-3; specs/003-governance-depth/plan.md pinned decision 1
Context¶
Contract-not-code requires declared data scopes to be enforced at the platform layer with undeclared access denied. The walking skeleton shipped only a stub synthetic-data service with no authentication, scope evaluation, or logging. Governance depth needed a real enforcement point that every data access flows through — and the generated perimeter (ADR-0007) makes that point unbypassable.
Decision¶
A new service, services/data-gateway (stdlib net/http, matching the 001
services), is the sole data path:
- A connector seam — one small interface per source type (
Synthetic,Postgres,S3), each serving only requests the gateway has already authorized — with implementationssynthetic(porting the bounded in-memory store from the 001 stub),postgres(reads, and DML where the scope grantsreadwrite; DDL always refused), ands3(object get/list against an S3-compatible endpoint). services/synthetic-datais retired at cutover; the operator's discovery ConfigMap repoints apps at the gateway.- Every request resolves the App CR's declared scopes (informer-cached), evaluates scope→connector access, and appends an access-log record for allow and deny alike before responding.
- Fail closed: any internal error — TokenReview failure, CR lookup miss, store write failure — returns deny.
Alternatives considered¶
- Evolve synthetic-data in place into the gateway — rejected: the gateway's contract (authn, scopes, logging, connectors) is a different service shape; porting the 60-line store is cheaper than mutating a deployed contract.
Consequences¶
Scope enforcement and access logging become platform guarantees rather than app behavior, and the per-app access log completes the evidence chain's "what data does it touch" half. Gateway readiness requires a writable log store — "can't log → don't serve". One recorded deviation (plan Complexity Tracking): the connector baseline ships two of the four declared v1 sources — Postgres and S3 — plus the synthetic source every sandbox app defaults to; internal REST and warehouse connectors are deferred as pre-v1 follow-ups, because two real connector shapes (relational, object) prove the contract generalizes and shipping all four would delay enforcement depth.