Change Data Capture Pipeline  ·  View 19 of 21  ·  Assurance

Security — Trust Zones

Four zones, and the one control that has to sit upstream of the log to work at all.

Editable source SVG draw.io All views
Source estate — application-owned, highest sensitivity PostgreSQL primaries no platform write path Read replicas Replication role replication + SELECT only Capture zone — the only reader of the source Capture plane workload identity Column masker regulated values never logged Secret Manager 90-day rotation Platform zone — change log and projection Operator API privileged actions Change log CMEK at rest Appliers per-sink identity Changelog archive crypto-shreddable Sink and consumer zone — tenant-scoped BigQuery per-tenant datasets Search index Consumers never see the raw log WAL, read-only masked by offset per tenant scoped SQL pause Security — Trust Zones and What Crosses Them External / third party Security / platform Interface / broker Queue / topic Application we own Data store synchronous event / async failure / alternate The masker is inside the capture zone deliberately: a regulated value that reaches the log can only be deleted, never un-logged. v 1.0 · owner Data Platform Architecture · date 2026-10

Decisions

  • Column masking happens at capture, before the log. A regulated value that reaches the log can only be deleted afterwards, never un-logged (ADR-07).
  • The capture identity holds replication and SELECT only: this platform structurally cannot write to a source.
  • Tenant isolation is enforced at the sink by per-tenant datasets, never by trusting a consumer's WHERE clause.

Assumptions

  • Source credentials rotate at most every 90 days; the change log and archive are encrypted with customer-managed keys.
  • Erasure in the archive is by crypto-shredding, which requires a per-subject key boundary decided in Phase 3.

Risks

  • The archive is the longest-lived copy of personal data in the estate at 13 months; its erasure story is the weakest part of this design and is named as such.
  • A masking rule added after a table is live does not retrospectively clean the log — it needs a re-snapshot and an archive rewrite.