Capability group 05

Data governance & isolation

SS-02 is the platform's only database plane (ADR-0056): every shared service and app gets state by claim, so tenancy, backups, credentials, audit and encryption are solved once, not per service. Tenant isolation is database-enforced where it can be (Postgres RLS) and mechanically-guarded where it cannot (MySQL app-filter). A recorded boundary (ADR-0068) keeps analytics in Prism, not reaching into operational databases.

Only-data-plane · placement · Prism boundary

0 rows
cross-tenant read (CI pen-test)
1 plane
no embedded / per-service DBs
per-tenant
KEKs in Vault Transit, no cloud KMS

Sub-capabilities

One plane, hard tenant boundaries, and an explicit analytics frontier.

The only-data-plane guarantee

All database requirements go through SS-02 (ADR-0056). No other or embedded engine is allowed on the platform — SQL, KV/cache, vector, full-text and object storage are all claims. That single door is what makes tenancy, audit and encryption uniform.

Tenant→database placement & isolation

Placement (ADR-0071) records where a relational tenant lands and how it is isolated: Postgres+single → shared instance with FORCE ROW LEVEL SECURITY; MySQL+single → shared instance with an application-enforced tenant_id discriminator and the TenantScope guard; MySQL+multi → TiDB. The MySQL asymmetry is stated honestly, not pretended away.

Prism analytics boundary

SS-02 owns operational claims; SS-09 Prism owns governed analytics and SS-06 VRQGO owns observability/audit analytics. Analytics engines (ClickHouse, Iceberg, Trino) are reserved substrate behind Prism — direct analytical reach-in to service databases is forbidden; facts land via CDC/batch.

Per-tenant encryption keys

At-rest data is envelope-encrypted with a per-tenant key-encryption-key held in Vault Transit; KEK rotation never re-encrypts the data. Cloud KMS is forbidden by a sovereignty invariant — keys never leave the platform.

Tamper-evident audit chain

Every audited action — every claim, lease, rotation, placement move — is appended to a Vault-Transit-signed hash chain (ADR-0014). Removing or modifying any past entry is detectable; retention runs to 7 years on Enterprise.

Endpoints

5 real operations on the /api/v1 contract.

Method + path straight from the SS-02 OpenAPI spec. Governed routes take an SS-01 bearer token and, where marked, an X-Tenant-Id; the S3 wire gateway authenticates with AWS SigV4 instead.

GET/api/v1/claims/{name}/placementbearertenant

Read placement + serve the Postgres RLS DDL / MySQL discriminator DDL (?tables=…).

POST/api/v1/claims/{name}/placementbearertenant

Declare the placement requirement; the policy decides target + isolation.

GET/api/v1/engines/catalogbearer

Boundary + license posture: which engines are operational claims vs Prism-reserved.

POST/api/v1/claims/{name}/leasesbearertenant

Vault-held, audit-chained credential lease — the platform's record of access.

GET/api/v1/object/usagebearertenant

Metered usage the SS-60/SS-10 chargeback path reads (zero-rated vs billable).

Worked example

Read the exact RLS isolation the platform enforces.

Read the exact RLS isolation the platform enforces · bash
# For a shared-Postgres tenant, placement emits the RLS setup as DDL.
# Ask for it and you get exactly the isolation the database enforces.
curl "$BASE/claims/orders/placement?tables=orders,line_items" \
  -H "Authorization: Bearer $TOKEN" -H "X-Tenant-Id: acme"
#   → {"target":"shared-postgres","isolation":"rls",
#      "naming":"schema t_acme",
#      "ddl":"CREATE SCHEMA t_acme; CREATE ROLE t_acme NOLOGIN;
#             ALTER TABLE orders ENABLE ROW LEVEL SECURITY;
#             ALTER TABLE orders FORCE ROW LEVEL SECURITY;
#             CREATE POLICY tenant_isolation ON orders
#               USING (tenant_id = current_setting('app.tenant_id'))
#               WITH CHECK (tenant_id = current_setting('app.tenant_id'));
#             …"}
# FORCE so even the table owner cannot bypass. A cross-tenant read
# returns ZERO rows — verified by an automated pen-test in CI.

For MySQL/TiDB the same endpoint returns the discriminator DDL and states plainly that the column enforces nothing — the platform/dbaas.TenantScope guard does, refusing any query that isn't bound by tenant_id.

In the architecture

Where it sits on the data plane.

Governance is not a bolt-on: because there is one data plane, tenancy (ADR-0019), the audit hash chain (ADR-0014), per-tenant KEKs and metering (SS-60 → SS-10) are wired into every claim by construction. The placement policy and admission catalogue are pure, table-tested functions; the Prism boundary is enforced by keeping analytics engines off the claim menu entirely.

ADR-0056DBaaS is the only database planeADR-0068DBaaS/Prism analytics boundaryADR-0071Tenant→database placement policyADR-0019MultitenancyADR-0014Tamper-evident audit chain