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.

Domains exchange data only through published APIs or event streams Two isolated spatial domains. Within each domain, private storage and compute feed a public API and event endpoint. The only sanctioned path between Domain A and Domain B runs from one domain's public API to the other's, labelled published API or event stream only. A direct connection between the two domains' private storage layers is drawn dashed and crossed out, marked as blocked: no shared storage or direct table joins. Domain A Domain B Storage & compute Public API + events Public API + events Storage & compute published API / event stream only blocked: no 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 email 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.

rego
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:

sql
-- 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:

yaml
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.

  1. Routing proxy rejection (HTTP 403/404). Verify the X-Domain-Id header matches the provisioned namespace and check the sidecar access logs for RBAC_DENIED events. 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.

  2. Policy evaluation denial (OPA allow = false). Replay the exact input with opa eval -i config.json -d boundary.rego "data.spatial.domain_boundary.allow". A false result with a matching domain_id almost always means the storage_uri escaped the domain prefix or the CRS is off-allowlist. Remediation: correct the storage URI in the pipeline config; never widen crs_allowlist to force a pass.

  3. Cross-domain storage escape. When a pipeline references an object outside its prefix, inspect the violation messages 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.

  4. RLS permission denial (PostgreSQL error 42501). Confirm app.current_domain_id is 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.

  5. Boundary manifest / catalog drift. When consumers report a missing or stale product, compare the catalog’s boundary_version against 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.

  6. 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.

  7. Idempotency key collision on boundary registration. Look up the existing idempotency_key and compare boundary_version timestamps to detect stale retries. Remediation: if the manifest matches, return the existing record; if it differs, reject with 409 Conflict and require an explicit boundary_version bump.

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.