Scoping Rules for Spatial Products

Scoping rules are the executable contract that decides what a spatial product is allowed to contain, publish, and expose before it ever reaches a consumer — the admission gate that keeps a federated geospatial estate from drifting back into a monolith.

Enterprise spatial platforms require deterministic scoping mechanisms to prevent architectural bleed, enforce domain autonomy, and guarantee predictable product delivery. When an organisation moves off a monolithic geodatabase toward domain-aligned ownership, scoping rules establish the immutable boundary between what a domain team controls and what the shared platform guarantees. This guide sits inside the Geospatial Data Mesh Fundamentals reference and assumes you have already separated your estate into autonomous domains as described in Spatial Domain Boundary Design. Where boundary design answers who owns this geometry, scoping rules answer under exactly what coordinate reference system, extent, resolution, and access contract may this product be published — the difference between a soft organisational convention and a gate that rejects a non-conforming manifest at publication time. The most granular field-by-field reference for those gates lives in Defining scoping rules for enterprise spatial products.

Figure — Scoping rules as policy-as-code: a manifest must clear CRS, extent, and resolution gates before it can publish to the mesh.

Scoping rules as a sequential admission gate for a spatial product manifest A product manifest enters at the top and passes through three sequential gates: CRS in the domain allowlist, bounding box within the domain extent, and resolution within the limit. Passing every gate publishes the product to the mesh; failing any single gate routes the manifest to a single shared reject-publication outcome on the right. Product manifest crs · extent · resolution pass pass pass CRS in allowlist? Bbox within domain extent? Resolution within limit? Publish to mesh indexed · routable fail fail fail Reject publication hard fail · audited

Architectural Boundaries & Design Rationale

Scoping rules exist because spatial coupling is silent. Two domains can share an EPSG code, a tile matrix set, or a column name and appear interoperable while quietly accumulating dependencies that fail only under reprojection, rescaling, or topology repair. A monolithic geodatabase masks this by forcing one CRS and one schema registry on everyone; a federated mesh removes that crutch, so the platform must replace implicit agreement with an explicit, machine-checked contract. A scoping rule is that contract expressed as policy-as-code: a manifest declares its coordinate reference system, spatial extent, resolution, geometry type, and service-level targets, and the platform admits the product only if every declared field clears a gate.

The failure modes this pattern prevents are concrete. Extent bleed occurs when a domain publishes geometry outside its assigned bounding box — a hydrology domain emitting features in a neighbouring catchment — which corrupts federated query results and lineage. Resolution leakage occurs when a sub-metre raster is published into a contract that consumers expect to be coarse, breaking both bandwidth budgets and, frequently, data-classification rules. CRS drift occurs when a product silently changes projection between versions, so downstream joins that assumed EPSG:4326 now misalign by hundreds of metres. Schema coupling occurs when a consumer reaches past the published API into a domain’s internal geometry types. Scoping rules close each of these by making the conforming path the only path to publication.

Because scoping is enforced at admission rather than at read time, it composes cleanly with the rest of the mesh. The routing layer described in the Federated Ownership & Routing Architecture trusts that any product reaching it has already cleared its CRS and extent gates, so cross-domain routing strategies can dispatch on declared metadata without re-validating geometry. The productization discipline from Product Thinking for GIS Datasets supplies the SLA fields a scoping rule binds, and Metadata Cataloging for Raster/Vector supplies the index those declarations are written into. Scoping is the gate; those capabilities are the systems on either side of it.

Specification & Contract Reference

A spatial product manifest is the unit a scoping rule evaluates. Every field below is mandatory; a missing or out-of-range field is a hard rejection, never a warning. CRS identifiers use EPSG codes, extents are expressed in the product’s declared CRS, and resolution is metres-per-pixel for raster or coordinate precision (decimal places) for vector.

Manifest field Type Constraint / gate Example
domain string Must match an owned domain in the boundary registry hydrology
crs string Must be in the domain CRS allowlist EPSG:4326
extent_bbox float[4] Must be fully contained in the domain’s assigned extent [5.8, 47.2, 10.5, 55.1]
geometry_type enum One of point|line|polygon|raster; immutable across minor versions polygon
resolution float <= domain max for raster; >= declared precision for vector 10.0 (m/px)
version string v<semver>-crs:<epsg>-res:<n>m; CRS or resolution change forces a major bump v1.2.0-crs:EPSG:4326-res:10m
max_query_latency_ms int Bound to the published SLA; enforced at the gateway 200
refresh_frequency_hours int Freshness contract surfaced in the catalog 24
classification enum open|internal|restricted; gates resolution and consumer role internal

The versioning convention is load-bearing. A string like v1.2.0-crs:EPSG:4326-res:10m encodes the two attributes that most often break consumers — projection and resolution — directly in the identifier, so a change from EPSG:4326 to EPSG:3857 or from 10m to 1m is forced to a new major version rather than smuggled into a patch. The geometry contract carried in geometry_type and the per-tile schema are owned upstream of routing by Schema Contracts for Vector Tile Data; a scoping rule references that contract rather than redefining it, which keeps a single source of truth for what fields a tile may carry.

Production Implementation

Scoping is enforced at three layers — routing admission, catalog registration, and access evaluation — and each layer must be idempotent (re-applying the same manifest yields the same state, never a duplicate) and zero-trust (no request is admitted on network position alone).

The routing layer rejects any request whose declared domain and CRS headers do not match an authorised destination. This is the same gateway discipline covered in API Gateway Mapping for GIS Services, applied here as a scoping gate. Note the explicit deny route — anything not matching the domain header returns HTTP 400 rather than falling through to a default backend.

yaml
# istio-virtualservice-scoping.yaml — applied via GitOps for idempotent reconciliation
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: spatial-domain-router
  namespace: platform-gateway
spec:
  hosts:
  - api.spatial-platform.internal
  http:
  - match:
    - headers:
        x-spatial-domain:
          exact: "hydrology"
        x-crs-code:
          exact: "EPSG:4326"
    route:
    - destination:
        host: hydrology-processor.hydrology.svc.cluster.local
        port:
          number: 8080
    headers:
      request:
        remove: ["x-geometry-type"]   # strip internal type to prevent implicit schema coupling
  - match:
    - uri:
        prefix: "/"
    fault:
      abort:
        httpStatus: 400               # zero-trust default-deny: unmatched scope is rejected at the edge
        percentage:
          value: 100
    route:
    - destination:
        host: hydrology-processor.hydrology.svc.cluster.local
        port:
          number: 8080

Catalog registration promotes a raw asset to a published product only after the manifest clears schema and extent validation. Driving it through ArgoCD makes the operation idempotent: re-syncing the same revision reconciles to the same catalog entry instead of creating a duplicate during a pipeline retry or network partition.

yaml
# argocd-catalog-sync.yaml — declarative, idempotent product registration
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: catalog-sync-hydrology
spec:
  project: data-mesh
  source:
    repoURL: https://git.platform.internal/spatial-catalogs.git
    targetRevision: main
    path: hydrology/v1.2.0-crs-EPSG-4326-res-10m
    plugin:
      name: spatial-catalog-validator
      env:
      - name: VALIDATE_SCHEMA
        value: "iso-19115-3"          # metadata schema compliance
      - name: ENFORCE_EXTENT
        value: "true"                 # reject geometry outside domain bbox
      - name: ENFORCE_IDEMPOTENCY
        value: "true"
  syncPolicy:
    automated:
      prune: true
      selfHeal: true
    syncOptions:
    - CreateNamespace=true
    - RespectIgnoreDifferences=true
  destination:
    server: https://kubernetes.default.svc
    namespace: spatial-catalog

Access evaluation enforces the resolution and classification gates at request time. The following OPA/Rego policy denies by default, admits only when the consumer’s role matches the product’s domain role, confirms the requested bounding box stays inside the product extent, and blocks sub-metre raster access without an explicit approval grant.

rego
# scoping.rego — default-deny spatial extent and resolution policy
package spatial.access

import rego.v1

default allow = false

allow if {
    # consumer role must match the product's domain clearance
    input.user.roles[_] == input.resource.domain_role
    # requested bbox must stay inside the published product extent
    input.request.bbox.latitude_max <= input.resource.max_lat
    input.request.bbox.latitude_min >= input.resource.min_lat
    # high-resolution rasters require an explicit grant
    resolution_authorized
}

# sub-metre rasters need an explicit approval; coarser data is allowed
resolution_authorized if {
    input.resource.resolution_meters >= 1.0
}

resolution_authorized if {
    input.user.approvals[_] == "high-res-spatial"
}

Compile and distribute the policy from a central registry, and evaluate it in the service-mesh sidecar so every product endpoint enforces the same gate. Align denial responses with the OGC API - Features specification so consumers receive a standard, machine-readable error rather than an opaque 403.

Diagnostic Runbook

When a product fails to publish or a consumer is unexpectedly denied, work the gates in admission order — header propagation first, then registry sync, then policy, then artifact and SLA.

  1. Confirm header propagation. A 404 on a spatial endpoint almost always means the x-spatial-domain or x-crs-code header never reached the gateway. Inspect the route table with kubectl get vs -n platform-gateway -o yaml and replay the request with the headers set explicitly via curl -H "x-spatial-domain: hydrology" -H "x-crs-code: EPSG:4326". A 400 here confirms the default-deny route fired because the headers did not match.
  2. Verify catalog sync state. A registration that never appears means the validator rejected the manifest or the sync stalled. Run argocd app get catalog-sync-hydrology and read the spatial-catalog-validator pod logs; a schema or extent failure halts promotion by design.
  3. Re-run the extent gate locally. Reproduce an extent rejection before touching the policy: ogrinfo -so -al product.gpkg reports the layer envelope, which you compare against extent_bbox in the manifest. Geometry outside the declared box is the root cause, not the gateway.
  4. Evaluate the access policy offline. For a 403, capture the OPA input and run opa eval -i input.json -d scoping.rego 'data.spatial.access.allow'. A false result with a matching role usually means the requested bbox exceeded max_lat/min_lat or the consumer lacked the high-res-spatial approval.
  5. Check version and CRS alignment. If consumers report misaligned joins, compare the version strings: a silent CRS or resolution change should have forced a major bump. Mismatched crs: segments between producer and consumer versions are the signal.
  6. Validate artifact integrity. Before blaming scope, confirm the published artifact matches what was registered — verify the signature with cosign verify and the manifest checksum, so a corrupted upload is not misread as a policy denial.
  7. Trace an SLA breach to a layer. If max_query_latency_ms is exceeded, trace the request across compute nodes and inspect spatial index health (pg_stat_user_tables for fragmentation) before scaling — an unmaintained index, not insufficient capacity, is the common cause.

SLA Targets & Performance Baselines

Scoping rules bind these targets to the manifest so the gateway and observability stack enforce them rather than treating them as documentation. Tie alert thresholds to product SLAs, not to generic infrastructure metrics.

Metric Target Alert threshold Remediation action
Manifest admission latency < 2 s > 5 s for 3 consecutive syncs Inspect validator pod; check schema registry connectivity
Query latency (p95) <= max_query_latency_ms (e.g. 200 ms) p95 > target for 5 min VACUUM ANALYZE vector store; scale read replicas
Extent-violation rejections 0 admitted any admitted out-of-extent product Audit producer pipeline; tighten ENFORCE_EXTENT
Policy denial rate < 1% of authorised consumers > 5% sustained 10 min Reconcile consumer RBAC against domain_role
Catalog sync drift 0 (GitOps reconciled) OutOfSync > 15 min Re-sync ArgoCD app; validate manifest checksum
Product freshness <= refresh_frequency_hours overdue by 25% Trigger refresh job; alert domain steward

Governance & Compliance Notes

Scoping rules are governance expressed as code, so every gate decision must leave an audit trail. Write each admission and denial — manifest hash, evaluated CRS, extent, resolution, and the policy decision — to an immutable ledger, so a compliance reviewer can reconstruct why any product version was published or rejected. The OPA decision log and the GitOps commit history together form that record without a separate bespoke system.

Lifecycle transitions inherit the same discipline. Marking a product deprecated should be idempotent: it routes legacy consumers to a migration endpoint while preserving historical query access for a defined retention window, and it never silently deletes a version that lineage still references. The state machine that governs those transitions — experimental, production, deprecated, archived — is detailed in Spatial Product Lifecycle Management; scoping rules are simply the admission gate that each new version must clear before it can advance through it.

Jurisdictional constraints attach to the classification and resolution fields. Sub-metre imagery and personally locatable vector data frequently carry residency or export restrictions, so the resolution gate doubles as a compliance control: a restricted product cannot be admitted at a resolution finer than policy allows, regardless of consumer role, and cross-border access is denied at the same OPA layer that enforces extent. Keeping these constraints in the same policy-as-code path as routing means a regulatory change is a versioned policy commit, not a manual audit.