Spatial Domain Boundary Design
Spatial domain boundary design is the foundational discipline that decides where one owned spatial product ends and another begins — and it is the contract every other concern in Geospatial Data Mesh Fundamentals ultimately depends on. Establishing strict boundaries requires a deliberate departure from monolithic GIS data lakes and centralized ETL pipelines: instead of routing all raster ingestion, vector topology validation, and coordinate transformation through a single enterprise geodatabase, each domain operates as an autonomous, self-contained product unit with explicit ownership, isolated compute and storage, and standardized interoperability contracts. This page is written for the data architects, platform engineers, and GIS data stewards who draw those lines and enforce them in production. It sits beside Scoping Rules for Spatial Products, which decides what belongs in a domain, while this reference decides how the resulting perimeter is isolated, validated, and routed. Traditional architectures create cascading latency, schema contention, and single-point governance bottlenecks; domain-driven spatial architecture inverts that model by enforcing isolation at the network, IAM, and catalog layers, so cross-domain exchange happens exclusively through published APIs, event streams, or federated query endpoints — never through direct table joins or shared scratch space.
Figure — Domains exchange data only through published APIs or event streams, never through shared storage or direct table joins.
Architectural Boundaries & Design Rationale
A spatial domain boundary is a security and contract perimeter first, and an organizational convenience second. It exists because a centralized geodatabase couples every team’s failure modes: one domain’s CRS drift, schema mutation, or topology corruption propagates silently to every consumer that shares the same tables. By making the boundary explicit and policy-enforced, a producer can re-project, re-tile, or re-version its products without negotiating a change window with the entire enterprise. This is the operational consequence of the shift detailed in Data Mesh vs Traditional GIS Architecture: once the canonical record no longer lives in one shared store, the boundary itself becomes the unit of governance.
A correctly designed boundary prevents four concrete failure modes that recur in centralized spatial estates:
- Silent cross-domain joins. A consumer issues a query whose bounding box straddles two domains and unknowingly mixes products with incompatible CRS, resolution, or freshness SLAs. The boundary forces the join to happen through a contracted federated query that surfaces the mismatch instead of hiding it.
- Schema contention. Two teams sharing a geodatabase serialize their migrations behind one another. Isolated storage removes the contention entirely — each domain owns its own schema evolution cadence.
- Ownership ambiguity. An asset lands in shared storage with no enforceable
product_owner_id, leaving lineage and incident response with no accountable party. A boundary that rejects unowned writes makes accountability structural. - Governance fan-out. A single shared store concentrates every access decision into one IAM policy that nobody fully understands. Per-domain policy keeps each decision local and auditable.
The boundary is realized at three layers simultaneously, and a defect in any one of them defeats the other two. At the network layer, pod-to-pod and egress traffic is restricted to explicitly declared namespaces so that no workload can reach storage it was not granted. At the IAM layer, every principal is scoped to a single domain_id and write roles are enumerated rather than inherited. At the catalog layer, the only discoverable surface for a domain is its published product manifest — direct storage URIs are never advertised. Producers publish; they do not expose. Consumers subscribe; they do not reach in. The zero-trust posture this enforces is the same one that Cross-Domain Routing Strategies applies to query traffic across the wider Federated Ownership & Routing Architecture.
For the formalized boundary-validation matrices and anti-pattern checklists that operationalize this rationale, see How to define domain boundaries for geospatial data.
Specification & Contract Reference
Every spatial domain publishes a boundary manifest that codifies its perimeter as a versioned, machine-readable contract. The manifest is the single source of truth that network policy, IAM scopes, and the federated catalog all bind to — none of them may invent their own view of where the boundary lies. The mandatory contract surface is as follows.
| Field | Type | Required | Constraint / Convention |
|---|---|---|---|
domain_id |
string | yes | Matches ^domain_[a-z0-9_]+$; bound to IAM scope and RLS context |
product_owner_id |
yes | Accountable steward for boundary changes and incidents | |
storage_uri_prefix |
string | yes | Single authoritative prefix, e.g. s3://mesh-prod/cadastral/; no wildcards |
spatial_extent |
object | yes | WKT/GeoJSON envelope defining the domain’s geographic perimeter |
crs_allowlist |
array | yes | Approved EPSG codes, e.g. [4326, 3857, 32633]; cross-domain joins reject anything else |
geometry_precision_m |
number | yes | Asserted coordinate precision in metres; > 0; gates topology validation |
published_interfaces |
array | yes | API/event endpoints exposed to consumers; storage URIs are never listed here |
tile_matrix_set |
enum | raster only | WebMercatorQuad | WorldCRS84Quad; aligns WMTS/XYZ schemes across domains |
topology_rule_set |
enum | vector only | none | planar | network | 3d_solid |
schema_version |
string | yes | v1.2.0-crs:EPSG:4326-res:10m site convention; monotonic per domain |
boundary_version |
string | yes | Bumped on any extent, CRS, or interface change; consumers pin to it |
The isolation and routing contract is carried in transport headers and policy inputs rather than the payload, so that the perimeter can be enforced before a request ever reaches storage:
| Surface | Key | Purpose |
|---|---|---|
| HTTP header | X-Domain-Id |
Selects the domain partition; matched by the routing sidecar |
| HTTP header | X-Spatial-Extent |
WKT/GeoJSON envelope evaluated against the domain perimeter |
| Session var | app.current_domain_id |
Activates PostgreSQL Row-Level Security for the connection |
| Policy input | input.config.storage_uri |
Validated against the domain’s storage_uri_prefix |
| Policy input | input.body.crs_epsg |
Validated against the domain crs_allowlist |
| Idempotency key | SHA-256(domain_id ‖ storage_uri_prefix ‖ boundary_version) |
Conflict-resolution key for boundary registration |
CRS identifiers are governed at the boundary, not deferred to consumers: only codes in the domain crs_allowlist may be registered, because an unapproved projection silently breaks every cross-domain spatial join downstream. EPSG codes extend beyond four digits — UTM zone codes such as EPSG:32633 are five-digit integers — so any validation range must admit five-digit values. Geometry precision is carried explicitly in geometry_precision_m: a vector product that asserts sub-metre topology but is stored at coarser precision will fail planar topology validation at the perimeter rather than corrupting a consumer. The interface contract aligns with Schema Contracts for Vector Tile Data so that a domain’s published tile schema and its boundary manifest never diverge.
Production Implementation
Boundary enforcement must be idempotent and zero-trust by default: repeated pipeline executions converge to one canonical perimeter, and no configuration is admitted without an explicit policy decision. The following OPA/Rego policy demonstrates boundary validation for infrastructure-as-code pipelines. It denies by default and admits a configuration only when the declared storage URI falls under the domain’s authoritative prefix and the requested CRS is on the domain allowlist — anything not explicitly permitted is rejected, and every denial emits structured diagnostic metadata for the audit trail.
package spatial.domain_boundary
import rego.v1
# Zero-trust: deny unless a rule explicitly admits the configuration.
default allow := false
# Authoritative per-domain storage prefixes and approved CRS sets.
domain_prefix := {
"cadastral": "s3://mesh-prod/cadastral/",
"hydrology": "s3://mesh-prod/hydrology/",
}
crs_allowlist := {4326, 3857, 32633}
# Admit only if storage stays inside the domain prefix AND the CRS is approved.
allow if {
prefix := domain_prefix[input.domain_id]
startswith(input.config.storage_uri, prefix)
input.config.crs_epsg in crs_allowlist
}
# Diagnostic metadata for audit logs on every denied configuration.
violation contains {"msg": msg} if {
not allow
msg := sprintf(
"Boundary violation: domain %q attempted %q with CRS %d",
[input.domain_id, input.config.storage_uri, input.config.crs_epsg],
)
}
Run the policy as an admission step before any merge — opa eval -i config.json -d boundary.rego "data.spatial.domain_boundary.allow" in CI, or the OPA HTTP API at runtime — and deploy it through a GitOps controller so that policy drift is corrected automatically on every reconcile. Because the same manifest backs the network and IAM layers, the perimeter is enforced three times independently and no single bypass can leak a product across a boundary.
The database layer carries its own copy of the perimeter through Row-Level Security bound to domain_id, so isolation holds even if an application bug forgets to filter:
-- Idempotent domain provisioning: re-running yields the same perimeter.
CREATE SCHEMA IF NOT EXISTS domain_cadastral;
ALTER SCHEMA domain_cadastral OWNER TO platform_admin;
ALTER TABLE domain_cadastral.spatial_products ENABLE ROW LEVEL SECURITY;
CREATE POLICY domain_isolation_policy ON domain_cadastral.spatial_products
USING (domain_id = current_setting('app.current_domain_id', true));
Network isolation is declared with a default-deny posture so workloads can reach only the namespaces their domain manifest authorizes. A Kubernetes NetworkPolicy that selects the domain’s pods and whitelists ingress from only its own namespace makes the boundary structural rather than advisory:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: cadastral-boundary
namespace: domain-cadastral
spec:
podSelector: {} # all pods in the domain namespace
policyTypes: ["Ingress", "Egress"]
ingress:
- from:
- namespaceSelector:
matchLabels:
domain-id: domain-cadastral # only same-domain traffic
egress:
- to:
- namespaceSelector:
matchLabels:
role: api-gateway # outbound only via published gateways
Diagnostic Runbook
Platform engineers must maintain deterministic diagnostic pathways for boundary failures. The following steps isolate the most common failure modes in production, from header propagation through policy evaluation to registry sync.
-
Routing proxy rejection (HTTP 403/404). Verify the
X-Domain-Idheader matches the provisioned namespace and check the sidecar access logs forRBAC_DENIEDevents. Confirm the requested extent actually intersects the domain perimeter before assuming a misconfiguration:sql SELECT ST_Intersects( ST_MakeEnvelope(xmin, ymin, xmax, ymax, 4326), domain_boundary ) FROM domain_registry WHERE domain_id = 'domain_cadastral';Remediation: correct the header or adjust the boundary WKT, then reload the sidecar via its admin API.
-
Policy evaluation denial (OPA
allow = false). Replay the exact input withopa eval -i config.json -d boundary.rego "data.spatial.domain_boundary.allow". Afalseresult with a matchingdomain_idalmost always means thestorage_uriescaped the domain prefix or the CRS is off-allowlist. Remediation: correct the storage URI in the pipeline config; never widencrs_allowlistto force a pass. -
Cross-domain storage escape. When a pipeline references an object outside its prefix, inspect the
violationmessages emitted by the Rego policy — they name the offending URI directly. Remediation: repoint the pipeline at the domain’s authoritative prefix and re-run; the idempotent reconciliation converges without side effects. -
RLS permission denial (PostgreSQL error 42501). Confirm
app.current_domain_idis set at connection initialization and verify the policy attachment:sql SELECT policyname, cmd, qual FROM pg_policies WHERE tablename = 'spatial_products';Remediation: ensure the connection-pool middleware injects tenant context before executing queries.
-
Boundary manifest / catalog drift. When consumers report a missing or stale product, compare the catalog’s
boundary_versionagainst the Git-backed manifest commit hash. Remediation: trigger the webhook reconciliation loop and confirm the resolved version matches, following the same cadence as Domain Sync Protocols for Spatial Data. -
Cross-domain query latency spike. Trace network flows through service-mesh telemetry and verify egress rules. A spike usually means traffic is bypassing the published gateway via direct VPC peering. Remediation: audit egress rules, restrict to published API gateways, and disable any direct peering.
-
Idempotency key collision on boundary registration. Look up the existing
idempotency_keyand compareboundary_versiontimestamps to detect stale retries. Remediation: if the manifest matches, return the existing record; if it differs, reject with409 Conflictand require an explicitboundary_versionbump.
SLA Targets & Performance Baselines
Boundary guarantees are first-class product SLAs, not best-effort metrics. The following baselines apply per domain and feed the alerting rules that govern remediation.
| Metric | Target | Alert Threshold | Remediation Action |
|---|---|---|---|
| Boundary policy evaluation (p95) | < 25 ms | > 75 ms for 10 min | Cache the compiled Rego bundle; co-locate the OPA sidecar |
| Cross-domain leak attempts | 0 successful | any RBAC_DENIED bypass |
Page on-call; audit boundary policy and network rules |
| Manifest vs catalog drift | 0 version mismatch | > 0 for 1 reconcile cycle | Trigger webhook sync; pin consumers to boundary_version |
| Federated query latency (p95) | < 300 ms | > 600 ms for 5 min | Restrict to published gateways; split oversized extents |
| Boundary registration latency (p95) | < 400 ms | > 800 ms for 5 min | Scale admission workers; inspect policy hot path |
| Idempotency convergence | 100% | any forked domain_id perimeter |
Enforce boundary_version bump; dedupe manifests |
| CRS validation failures | 0 off-allowlist writes | any successful off-allowlist write | Block at admission; re-assert crs_allowlist |
Governance & Compliance Notes
Governance in a federated spatial estate is distributed but coordinated: domain product owners define interface contracts, GIS data stewards enforce quality and metadata standards, and platform engineers maintain the underlying isolation primitives. The boundary manifest is the policy-as-code hook that ties these roles together — it is version-controlled in a Git-backed registry, validated against an OGC API Records compliant profile, and reconciled to the enterprise catalog through a webhook-driven loop so that the declared perimeter and the enforced perimeter never diverge. Every boundary mutation must emit an append-only audit event capturing the actor (product_owner_id or service principal), the domain_id, the resolved idempotency_key, the prior and new boundary_version, and the policy decision — this is what lets compliance reconstruct exactly who changed which perimeter, when, and under which contract.
Jurisdictional and classification constraints attach at the boundary rather than downstream: products tagged with residency or restricted labels must be denied admission into any domain whose perimeter does not satisfy the corresponding constraint, and the OPA/Rego policy is the single enforcement point for those labels. When a domain bumps its boundary version, the change propagates through a versioned event stream; consumers subscribed to that stream adapt to the new perimeter automatically instead of breaking on an unannounced migration. Treating spatial boundaries as immutable, policy-enforced, version-controlled constructs is what eliminates the fragility of shared geodatabases while preserving the interoperability large-scale geospatial analytics depends on. Versioning, deprecation windows, and retirement of superseded boundaries are governed under Spatial Product Lifecycle Management, which keeps a retired perimeter queryable long enough for consumers to migrate safely.
Related
- Geospatial Data Mesh Fundamentals — parent reference and architectural overview
- Scoping Rules for Spatial Products — deciding what belongs inside a domain before drawing its perimeter
- Product Thinking for GIS Datasets — the ownership and SLA model the boundary enforces
- Metadata Cataloging for Raster/Vector — how the catalog registers what each boundary publishes
- How to define domain boundaries for geospatial data — boundary-validation matrices and anti-pattern checklists