6.6 Implementing Data Processing Segregation
Key Takeaways
Segregation separates identity from behavioral data, tenants from each other, production from test and analytics, and data collected for one purpose from other uses.
A token vault or identity mapping service lets analytics run on random pseudonyms while only an authorized service can resolve them to real identities.
Database-per-tenant isolation gives the strongest separation and per-tenant keys; shared schemas depend on row-level security enforced by the database, not application WHERE clauses.
PostgreSQL row-level security needs at least one permissive policy, and tenant context should be set with SET LOCAL inside a transaction so it cannot leak across pooled connections.
Non-production environments should hold synthetic or masked data, never raw production personal data.
6.6 Implementing Data Processing Segregation
Quick Summary: Segregation keeps personal data, and the processing that uses it, separated so that one compromise, one query, or one team cannot see everything. Privacy engineers separate identity from behavior, separate tenants from each other, separate environments (production, testing, analytics), and separate processing by purpose. The aim is to make linkage and misuse hard by design rather than relying on everyone following policy.
The BoK lists "implement data processing segregation" as a collection-stage control because segregation decisions are made when data enters a system: which store receives which fields, under which keys, and who can join them later.
Four Kinds of Segregation
| Kind | What Is Separated | Example Control |
|---|---|---|
| Identity from behavior | Direct identifiers vs. events and telemetry | A token vault maps user_id to a random pseudo_id; analytics stores see only pseudo_id |
| Tenant from tenant | One customer organization's data from another's | Database per tenant, schema per tenant, or row-level security |
| Environment from environment | Production data vs. development, testing, and analytics | No production personal data in test; masked or synthetic copies only |
| Purpose from purpose | Data collected for one purpose vs. other uses | Separate stores and keys for fraud data and marketing data, with purpose-checked access |
Environment segregation deserves special attention because test and staging systems usually have weaker access control and logging than production. Use synthetic data or masked copies (with consistent tokenization so joins still work), block production credentials in lower environments, and scan non-production stores for real personal data. Purpose segregation supports purpose limitation (Section 7.5): if marketing systems physically cannot read the security-only phone number store, function creep requires a deliberate, reviewable change rather than a quiet query.
Architectural Segregation: Decoupling Identity from Behavior
A critical failure mode in enterprise system design is the monolithic datastore pattern, in which direct personally identifiable information (PII)—such as legal names, email addresses, government identifiers, and billing records—resides in the same database tables or clusters as behavioral event streams, search histories, clickstream logs, and sensor telemetry.
Under this flawed model, any security breach, SQL injection, unauthorized internal query, or data export immediately links sensitive behavioral activities to real-world individuals.
The Dual-Datastore Segregation Pattern
Privacy-by-design architectures enforce architectural segregation by separating data across two isolated trust zones:
| Architectural Attribute | Identity Datastore (PII Vault) | Behavioral Datastore (Analytics Store) |
|---|---|---|
| Data Types Stored | Legal name, email, government ID, phone number, physical address, billing details | Clickstream events, query logs, browsing history, telemetry, recommendation weights |
| Primary Identifier | Real-world primary key (user_id, UUID v4) | Opaque, surrogate pseudo-identifier (pseudo_id) |
| Access Controls | Restricted role-based access; dedicated KMS keys; full audit logging; zero direct analyst access | Broad internal analytics access; data science pipelines; machine learning training clusters |
| Network Boundary | Isolated VPC / internal subnet; strictly bounded microservice API | Analytical data lake (S3/Delta Lake, BigQuery, Snowflake) |
| Replication Scope | Encrypted live replicas only; zero export to data warehouses | Widely replicated across analytical processing clusters |
The Tokenization and Identity Mapping Service
To correlate behavioral trends with user cohorts without exposing identities, systems deploy an isolated Identity Mapping Service (also known as a Pseudonymization Proxy or Tokenization Vault):
- When an event occurs, the client or edge gateway sends the event to the Ingestion Router.
- The Ingestion Router strips all direct identifiers and queries the Identity Mapping Service to exchange the real
user_idfor a cryptographically secure, randomized surrogate token (pseudo_id = f98c3e8a-2114-41b9-8c99-0129a084ef72). - The mapping table between
user_idandpseudo_idresides in a hardened, isolated database protected by dedicated envelope encryption. - Behavioral logs are committed to the data lake referencing only
pseudo_id. - If an analytical report requires contacting a specific cohort (e.g., notifying users affected by an operational issue), only an authorized compliance microservice with elevated privileges can submit the
pseudo_idlist to the mapping service to resolve the underlying contact information.
Multi-Tenant Data Isolation Architectures
In Software-as-a-Service (SaaS) and cloud-native applications, systems frequently process personal data belonging to thousands of independent enterprise tenants. Preventing tenant data bleed—where a query, indexing bug, or caching defect exposes Tenant A's customer PII to Tenant B—requires rigorous structural isolation.
+-----------------------------------------------------------------------------------+
| MULTI-TENANT ISOLATION MODELS |
| |
| 1. SILO MODEL (Database-per-Tenant) |
| +--------------------+ +--------------------+ +--------------------+ |
| | Tenant A Database | | Tenant B Database | | Tenant C Database | |
| | (Independent Keys) | | (Independent Keys) | | (Independent Keys) | |
| +--------------------+ +--------------------+ +--------------------+ |
| [Max Isolation, Zero Bleed Risk, Independent Retention & Crypto-Shredding] |
| |
| 2. BRIDGE MODEL (Schema-per-Tenant) |
| +-----------------------------------------------------------------------------+ |
| | Single Database Instance | |
| | +-----------------------+ +-----------------------+ +-----------------+ | |
| | | Schema: tenant_a | | Schema: tenant_b | | Schema: tenant_c | | |
| | +-----------------------+ +-----------------------+ +-----------------+ | |
| +-----------------------------------------------------------------------------+ |
| [Logical Isolation via SQL Namespaces, Shared Resources, High DDL Overhead] |
| |
| 3. POOL MODEL (Shared-Schema with Row-Level Security) |
| +-----------------------------------------------------------------------------+ |
| | Single Database Instance & Single Shared Schema | |
| | +-----------------------------------------------------------------------+ | |
| | | Unified Table (orders, users) with tenant_id Column | | |
| | | Postgres Row-Level Security: USING (tenant_id = current_setting('...')) | | |
| | +-----------------------------------------------------------------------+ | |
| +-----------------------------------------------------------------------------+ |
| [Highest Cost Efficiency, Operational Simplicity, Risk of App Logic Leakage] |
+-----------------------------------------------------------------------------------+
Comparison of Tenancy Architectures
| Tenancy Pattern | Architectural Description | Isolation Strength | Operational Overhead | Threat Vectors & Leakage Risks |
|---|---|---|---|---|
| Database-per-Tenant (Silo) | Each tenant possesses a dedicated physical or logical database instance with distinct credentials and KMS keys. | Highest | High: Managing schema migrations, connection pools, and infrastructure cost across thousands of instances. | Near-zero cross-tenant bleed. Threat limited to infrastructure-level misconfiguration or centralized administrative compromise. |
| Schema-per-Tenant (Bridge) | Tenants share a single database instance but operate in distinct SQL schemas (e.g., PostgreSQL namespaces selected via search_path). | Moderate | Moderate: Schema migrations require executing DDL across all schemas; database metadata limits and connection exhaustion. | SQL injection or ORM connection pool misconfiguration setting the wrong search_path can route queries to another tenant's schema. |
| Shared-Schema with RLS (Pool) | All tenants share the same database, schema, and tables. Every table includes a tenant_id column, and database policies filter rows. | Logical Only | Low: Single unified schema; trivial migrations; centralized connection pooling. | Severe: A missed WHERE tenant_id = ? clause, an ORM bypass, or a connection pool retaining session context can expose all tenant data. |
Enforcing Row-Level Security (RLS) in Shared-Schema Models
When operating a pooled architecture, reliance on application-layer code to append WHERE tenant_id = :current_tenant is an anti-pattern that inevitably results in data leaks. Instead, isolation must be enforced directly at the database engine level via Row-Level Security (RLS):
-- Enable Row-Level Security on the target table
ALTER TABLE customer_profiles ENABLE ROW LEVEL SECURITY;
-- Force security policies even for table owners
ALTER TABLE customer_profiles FORCE ROW LEVEL SECURITY;
-- Define tenant isolation policy using session context
-- (a permissive policy; a RESTRICTIVE policy alone would deny every row,
-- because PostgreSQL requires at least one permissive policy to grant access)
CREATE POLICY tenant_isolation_policy ON customer_profiles
USING (tenant_id = current_setting('app.current_tenant_id', true)::uuid);
Before executing any query on a pooled database connection, the application middleware must execute:
SET LOCAL app.current_tenant_id = 'e7b1c34a-9812-421b-8012-110022334455';
SET LOCAL (or set_config(..., true)) scopes the value to the current transaction, so it disappears at COMMIT or ROLLBACK and cannot leak into the next request that reuses the pooled connection. It has no effect outside a transaction block, so the middleware must open a transaction first. If the setting is missing, current_setting(..., true) returns NULL and the policy matches no rows, which fails closed.
A multi-tenant software-as-a-service platform processes sensitive healthcare records. The security architecture team must select a database tenancy model that guarantees the lowest possible risk of cross-tenant data bleed during application bugs while allowing distinct, customer-managed cryptographic keys per tenant. Which model best meets these criteria?
A shared-schema pool model with application-level WHERE clauses filtering every query by the tenant identifier.
A schema-per-tenant bridge model where all tenants share an identical database instance and encryption key.
A shared-schema pool model utilizing database engine Row-Level Security policies tied to session variables.
A database-per-tenant silo model providing completely isolated physical or logical database instances with distinct key management configurations.
A development team copies the full production customer database into a staging environment so testers can reproduce bugs. Staging has broad developer access and minimal logging. What is the best segregation fix?
Use synthetic or masked data in staging and block production credentials and raw exports there.
Encrypt the staging database with the same key used in production.
Move staging onto the same network segment as production so that the same firewall rules and monitoring apply to both.
Keep the full production copy but require developers to sign an acceptable use policy each quarter and complete annual privacy training.
A ride-hailing company collects riders' phone numbers for account security and also runs a marketing team that wants to send promotions. Which architecture best implements purpose segregation?
One customer table readable by all teams, with a comment column noting each field's purpose.
Keep security numbers in a separate, key-protected store usable only by authentication, and collect marketing contacts separately with consent.
A nightly export of the security phone numbers to the marketing platform, with the exported file deleted automatically after each campaign ends.
Hash the phone numbers with SHA-256 so marketing can use them without seeing the raw values.
Sections you finish are checked off in the contents.