Cloud Infrastructure · Multi-Region Design

Pinning Data to a Region Without Freezing the Control Plane

How residency constraints translate into placement rules, which metadata still leaks across borders, and why the control plane and data plane need different regionality.

A residency requirement says that certain data must not leave a jurisdiction. Implementations usually translate that into “store the database in a region inside the jurisdiction”, which satisfies the literal sentence and misses most of the actual data movement. Records are not the only thing that crosses a border. Backups, indexes, logs, metrics, traces, caches, key material, and the identifiers used to route requests all leave the region in a conventional multi-region deployment, and several of them carry the regulated content in a form that is still regulated.

Classifying what has to stay

The first design step is deciding which data is actually constrained. Residency rules attach to categories of data, not to tables, and one table often mixes categories: a support ticket row contains a customer identifier (regulated), a free-text body (possibly regulated), and a internal routing tag (not regulated). Column-level classification is what makes the constraint implementable.

Three practical classes:

Constrained content. Personal data, and whatever else the applicable rule names. It must be stored and processed only within the permitted jurisdiction. Any copy outside is a violation regardless of whether it is encrypted, with narrow exceptions that vary by regime and should not be assumed.

Derived data. Aggregates, indexes, and caches computed from constrained content. Whether these are constrained depends on whether they can be reversed to the original. A hash of an email address with a small input space is reversible by enumeration, so a “anonymized” analytics table keyed by such a hash is still constrained content. A count of tickets per day is not. The test is re-identification risk, not the presence of a transformation step.

Operational metadata. Timestamps, sizes, error codes, request identifiers. Usually not constrained, but the identifier is the trap: a request ID that is also the user’s account number, or a log line that includes the full URL with a query string containing an email, moves constrained content into the unconstrained class by accident.

The classification determines the topology more than any other input. If only the first class is constrained, a single-region data store with a global control plane works. If derived data is constrained too, the analytics pipeline must run in-region. If operational metadata is constrained, the observability stack must be regional, which is a much larger commitment because it touches every service.

The leaks that survive a regional database

Placing the primary database in the jurisdiction does not close the following paths, each of which is a real egress of constrained content.

Backups and snapshots. A snapshot copied to a second region for disaster recovery is a copy of the data in another jurisdiction. Cross-region backup replication is usually the single largest residency violation in an otherwise compliant design, and it is often enabled by default. The compliant alternatives are in-region redundancy across availability zones, or a backup region inside the same jurisdiction when the jurisdiction is large enough to have more than one.

Read replicas and caches. A cache is a copy. A session store that holds a user profile is a copy. A read replica placed near users in another jurisdiction to reduce latency is a copy. Each must be evaluated against the classification, and a cache with a TTL of minutes is still a copy for those minutes.

Search and analytics indexes. A full-text index contains the text. Shipping a change stream to a search cluster in another region ships the documents, whatever the cluster is called.

Logs and traces. Application logs routinely contain request bodies, error messages with record contents, and identifiers. A central log aggregation point outside the jurisdiction collects all of it. Trace spans often carry attributes that include user identifiers, and span export is usually configured globally because the tracing backend is a shared service.

Key management. If encryption keys are held in a global key service, the ciphertext can be stored in-region while the ability to decrypt it is controlled elsewhere. That is usually acceptable under a residency rule — the rule constrains the data, not the keys — but it is not acceptable under a rule that requires the data to be under local legal control, because a compelled disclosure elsewhere could reach the keys. The distinction between “data must stay” and “data must not be accessible from outside” changes the key architecture, and NIST’s key-management guidance treats key location and key custody as separate properties for exactly this reason.

Separating control plane from data plane

The architectural pattern that satisfies residency without duplicating an entire platform is a split between a global control plane and regional data planes.

The control plane holds configuration, deployment state, and identity for operators. It does not hold constrained content. It can be global, and being global is what makes operating many regions tractable: one place to define a service, one place to roll out a change, one inventory of what exists.

The data plane holds the records, the caches, and the per-request processing. It is regional, and a region’s data plane can run with no dependency on the global control plane for serving traffic. That independence is a residency property and an availability property at the same time: if the control plane is unreachable, the data plane keeps serving its existing configuration.

The failure mode of this split is configuration drift. A global control plane that pushes configuration into regions will, if it is unavailable, leave regions on the last configuration they received. That is the intended behaviour, but it means a change applied during a control-plane outage is applied partially, and the regions diverge. Reconciliations that require a control-plane round trip cannot run during the outage, so the divergence persists until the control plane returns.

A second failure mode is the shared dependency that quietly becomes a data path. A feature flag service, a rate limiter, or an authorization service that lives globally and receives request attributes is a data path even though it is drawn on the control-plane side of the diagram. Any such service that receives constrained content must be regionalized or must be changed to receive only non-constrained keys.

Identity and the residency of the user record

Authentication is where the split gets awkward. A user’s identity record — name, email, recovery factors — is constrained content in most regimes, so it lives in the user’s region. But a request arriving at a regional data plane must be authenticated, and the token presented may have been issued by an identity provider in another region.

The workable arrangement is that the identity provider issues a signed token containing the minimal claims needed for authorization, and the regional data plane validates the signature locally without fetching the user record. The token then becomes a small, non-constrained artifact, and the constrained record stays in its region. The token’s lifetime is the staleness bound for revocation: a revoked user can present a valid token until it expires, so the lifetime is a security parameter and shortening it forces more frequent re-authentication or more frequent token refresh round trips.

A token that carries the user’s email or full name as a claim defeats the arrangement, because it re-exports constrained content to every service that reads the token. Claims should be opaque identifiers plus coarse authorization attributes, with the constrained attributes fetched from the regional store only when a service actually needs them.

Proving the boundary rather than asserting it

A residency design that exists only in an architecture document is unverifiable. The boundary has to be observable, and the observations have to be cheap enough to keep running.

Three controls do most of the work:

Egress allowlists at the network layer. Each regional data plane permits outbound traffic only to a named set of destinations. Anything else fails closed, which turns an accidental cross-region call into an error instead of a silent copy. The allowlist is a configuration artifact and needs the same review discipline as a schema change.

Storage location assertions in the deployment path. Every resource that stores data declares its region, and the deployment pipeline rejects a resource whose declared region is outside the permitted set for its classification. This catches the default-region mistake, which is the most common cause of accidental placement: a queue, a bucket, or a log group created without an explicit region lands wherever the client’s default is configured.

Periodic content scanning of the unconstrained stores. Logs, traces, and metrics are sampled and scanned for patterns that indicate constrained content: email shapes, national identifier formats, known field names. A hit is a defect in the logging code, not in the storage layer, and the fix is redaction at the source. Scanning is a detector, not a control; it finds leaks after they have happened, which is why the first two controls matter more.

Residency as a routing constraint

The last piece is request routing. A user’s data lives in one region, so requests about that data must be served there. That makes the user’s region a routing key, and the routing layer must resolve it before it can send the request anywhere. Resolving it requires either a directory that maps user to region — a small, non-constrained index — or a signed claim in the token that names the region.

The latency consequence is that a user travelling or working away from their home region pays a cross-region round trip on every request. This is not avoidable: the data cannot be served from a local replica without creating a copy, and the copy is the thing the rule forbids. The honest design accepts the inter-region latency floor for those users, and the product decision is whether that is acceptable or whether the data model can be partitioned so that some of it is genuinely local.

What residency rules do not permit is the compromise that looks attractive on a latency chart: replicating the constrained data to every region for read locality and calling the replicas “caches”. A cache is a copy with a shorter lifetime, and the lifetime does not change the legal character of the data. Conflict resolution for two-region writes is the design space that opens when writes are allowed to land in more than one place — and under a strict residency rule, that space is usually closed.

References

  1. Regulation (EU) 2016/679 (General Data Protection Regulation), Chapter V — European Parliament and Council
  2. ISO/IEC 27018:2019 — Code of practice for protection of personally identifiable information in public clouds — ISO/IEC
  3. NIST SP 800-57 Part 1 Rev. 5 — Recommendation for Key Management — NIST