Spatial Product Lifecycle Management
The operational discipline that governs how a geospatial asset is provisioned, versioned, promoted, deprecated, and retired as an autonomous product inside a federated mesh.
Enterprise geospatial operations require a disciplined transition from monolithic GIS repositories to federated, domain-aligned data products. Spatial product lifecycle management establishes the operational framework for provisioning, versioning, routing, and retiring geospatial assets so that every tileset, coverage, and feature collection behaves as a versioned, SLA-bound product rather than a static file drop. This page 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 and constrained what each product may publish through Scoping Rules for Spatial Products. Where boundary design answers who owns this geometry and scoping answers what may be published, lifecycle management answers how a product moves safely from experiment to production and back out of service without breaking the consumers who depend on it. The intended readers are data architects, platform engineers, GIS data stewards, and enterprise platform teams who must make those transitions deterministic, observable, and reversible.
Figure — The managed lifecycle of a spatial product; each transition is gated by quality checks and deprecation windows.
Architectural Boundaries & Design Rationale
A spatial product must be treated as an independent domain boundary with explicit ingress and egress controls. The architectural shift moves away from shared enterprise geodatabases and centralized ETL orchestration toward decentralized ownership with standardized interoperability contracts. Lifecycle management is what keeps that decentralization from degenerating into chaos: without managed state transitions, a federated estate accumulates undocumented overwrites, silent projection changes, and orphaned tilesets that consumers still query. The lifecycle states — Experimental, Production, Deprecated, Archived — exist precisely so that every change to a product is an explicit, gated event rather than an in-place mutation.
The failure modes this pattern prevents are concrete. Silent overwrite occurs when a domain republishes the same version with different geometry, so a consumer that pinned v1.2.0 suddenly receives different features; immutable artifact registries close this by rejecting any write to an existing version tag. CRS drift occurs when a product changes projection between releases, so downstream joins that assumed EPSG:4326 misalign by hundreds of metres after an unannounced move to EPSG:3857; encoding the CRS into the version string and validating it at promotion closes this. Dangling consumption occurs when a product is deleted while live traffic still references it; the Deprecated and Archived states with explicit deprecation windows give consumers a bounded migration period instead of an abrupt failure. Cross-domain leakage occurs when a retired product’s compute plane is reused by another domain without re-scoping, which is why retirement must release routing and policy bindings, not just storage.
Platform engineers enforce these boundaries at the API gateway and service mesh layers, ensuring that vector tile requests, raster processing jobs, and metadata queries are routed exclusively to the owning domain’s compute plane. The routing patterns themselves are owned by the Federated Ownership & Routing Architecture reference and detailed in Cross-Domain Routing Strategies; lifecycle management consumes those routes and is responsible only for binding the correct product version to a route and unbinding it cleanly on retirement. Security boundaries are enforced through zero-trust network policies, attribute-based access control (ABAC), and cryptographic signing of spatial payloads, so a product that has transitioned to Deprecated can have its write path revoked while its read path remains available for the deprecation window. The canonical decoupling patterns this section builds on are codified in Spatial Domain Boundary Design, and the rationale for treating datasets as products at all is established in Product Thinking for GIS Datasets.
Specification & Contract Reference
Every lifecycle transition is governed by a declared contract. A product manifest carries the fields below, and the platform admits a transition only when each field validates against the gate for the target state.
Lifecycle states and gates
| State | Meaning | Entry gate | Read access | Write access |
|---|---|---|---|---|
| Experimental | Pre-production, breaking changes allowed | Schema-valid manifest registered | Domain team only | Domain team |
| Production | Stable, SLA-bound, consumer-facing | Quality gates + topology + CRS validation pass | All authorized consumers | CI/CD pipeline only |
| Deprecated | Superseded, read-only, migration window open | Successor version in Production | Existing consumers | None (frozen) |
| Archived | Retired, cold storage, routes released | Deprecation window elapsed, no live traffic | Restore-on-request | None |
Version string grammar
Versioning adheres to semantic conventions extended for geospatial context. A version tag encodes the projection and resolution so that a CRS or resolution change is impossible to ship without an explicit version bump:
v<major>.<minor>.<patch>-crs:<EPSG>-res:<resolution> — for example v1.2.0-crs:EPSG:4326-res:10m or v2.1.0-crs:EPSG:3857-res:0.5m.
| Field | Rule | Failure if violated |
|---|---|---|
major |
Increment on breaking schema or CRS change | Consumers receive incompatible geometry |
minor |
Increment on additive, backward-compatible change | None |
patch |
Increment on metadata or quality fix, geometry unchanged | None |
crs |
Must be one of the domain CRS allowlist (EPSG:4326, EPSG:3857, EPSG:32633) |
Reprojection misalignment downstream |
res |
Must satisfy the resolution limit declared in scoping rules | Bandwidth and classification breaches |
Routing and policy fields
| Field / header | Layer | Purpose |
|---|---|---|
X-Domain-ID |
Gateway | Pins a request to its owning domain’s compute plane |
X-Payload-Signature |
Gateway | Cryptographic signature of the spatial payload, verified per domain key |
productId |
Manifest | Stable identifier across all versions of a product |
processingProvenance.pipelineId |
Manifest | Upstream lineage anchor for catalog reconciliation |
spatialExtent / temporalCadence |
Manifest | Scoping fields; breaking changes require a major bump |
Manifest registration itself flows into the federated catalog described in Metadata Cataloging for Raster/Vector, which is the discovery surface consumers use to find a product version and its current lifecycle state.
Production Implementation
Three runnable artifacts cover the lifecycle: a zero-trust routing policy that pins live traffic to the owning domain, an idempotent manifest registration pipeline that feeds the catalog, and a GitOps promotion workflow that swaps product versions atomically.
Zero-trust routing policy (OPA / Rego)
Implementing ABAC at the gateway requires declarative policy-as-code. The following Open Policy Agent (OPA) Rego policy enforces spatial extent validation and CRS compliance before routing requests to downstream tile servers. The default-deny posture is the zero-trust requirement: a request is rejected unless every condition matches.
package spatial.gateway
import rego.v1
# Default deny — zero-trust posture
default allow = false
# Allow only if the request matches the owning domain's contract
allow if {
input.method == "GET"
input.path = ["tiles", domain, _, _, _, _]
domain == input.headers["X-Domain-ID"]
is_valid_crs(input.query["crs"])
within_spatial_extent(input.query["bounds"], data.domain_extents[domain])
}
is_valid_crs(crs) if {
crs in {"EPSG:4326", "EPSG:3857", "EPSG:32633"}
}
within_spatial_extent(bounds, extent) if {
bbox := split(bounds, ",")
min_x := to_number(bbox[0])
min_y := to_number(bbox[1])
max_x := to_number(bbox[2])
max_y := to_number(bbox[3])
min_x >= extent.min_x
min_y >= extent.min_y
max_x <= extent.max_x
max_y <= extent.max_y
}
Idempotent manifest registration
Metadata registration must be idempotent so that a CI/CD retry never creates catalog drift. The pipeline below validates each manifest against the schema, computes a deterministic content hash, and registers the product only when the hash differs from the catalog state — so re-running it is a no-op:
#!/usr/bin/env bash
set -euo pipefail
MANIFEST_DIR="./spatial-manifests"
SCHEMA_PATH="./schema/spatial-product-manifest.schema.json"
for manifest in "${MANIFEST_DIR}"/*.json; do
# 1. Schema validation (idempotent)
python3 -m jsonschema --instance "${manifest}" "${SCHEMA_PATH}"
# 2. Compute deterministic content hash
HASH=$(sha256sum "${manifest}" | awk '{print $1}')
# 3. Register only if the hash differs from catalog state
PRODUCT_ID=$(jq -r '.productId' "${manifest}")
EXISTING=$(curl -sf "${CATALOG_API}/products/${PRODUCT_ID}/hash" || echo "")
if [ "${EXISTING}" != "${HASH}" ]; then
curl -sf -X POST "${CATALOG_API}/products" \
-H "Content-Type: application/json" \
-d @"${manifest}"
echo "Registered: ${PRODUCT_ID}"
else
echo "Skipped (idempotent): ${PRODUCT_ID}"
fi
done
Atomic promotion and rollback (GitOps)
Promotion pipelines must enforce cryptographic checksums, spatial topology validation, and automated regression testing against baseline extents before a version reaches Production. Immutable artifact registries prevent unauthorized overwrites, while signed releases ensure supply-chain integrity. Leverage Kubernetes-native GitOps controllers to manage spatial tileset promotions so that a version swap is atomic and self-healing:
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: spatial-product-urban-landcover
spec:
project: geospatial-mesh
source:
repoURL: https://git.enterprise.internal/spatial-products/urban-landcover.git
targetRevision: v2.1.0-epsg:3857-res:0.5m
path: deploy/overlays/prod
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
- ApplyOutOfSyncOnly=true
destination:
server: https://kubernetes.default.svc
namespace: spatial-prod
Diagnostic Runbook
When a transition fails, work the following ordered checks; the first matching symptom is usually the root cause.
- Verify policy evaluation. Execute
opa eval -i input.json -d policy.rego "data.spatial.gateway.allow"to confirm the routing decision is deterministic. Afalseresult with a valid request usually means theX-Domain-IDheader was stripped upstream. - Trace mesh propagation. Use
istioctl analyzeor the equivalent service-mesh CLI to validate thatVirtualServiceandDestinationRuleobjects restrict cross-domain egress and that the retired version’s route was actually unbound. - Audit cryptographic signatures. Inspect
X-Payload-Signatureheaders against domain-specific public keys; reject requests with expired timestamps or mismatched CRS claims. - Detect schema and catalog drift. Run
python3 -m jsonschema --instance manifest.json schema.jsonto verify backward compatibility, and reject manifests that changespatialExtentortemporalCadencewithout a major bump. If the catalog returns inconsistent state, compareupdated_attimestamps against pipeline execution logs before forcing a re-register. - Validate topology before promotion. Run
ogrinfo -so -al tileset.gpkgand verify theGeometry TypeandLayer SRS WKTmatch the declared domain CRS. Mixed geometry types or a projection mismatch must block promotion. - Verify rollback. Execute
argocd app rollback spatial-product-urban-landcover --revision <previous-sync-id>and confirm p95 query latency returns to baseline within 90 seconds. - Confirm artifact integrity. Verify Cosign signatures with
cosign verify --key domain-public.pem <image-or-artifact>; an unsigned artifact must trigger immediate pipeline termination.
SLA Targets & Performance Baselines
Spatial products instrument standardized telemetry — tile cache hit ratios, raster processing queue depths, and metadata synchronization latency — codified as Prometheus alerting rules and enforced via admission controllers.
| Metric | Target | Alert threshold | Remediation |
|---|---|---|---|
| Tile availability | 99.95% | < 99.8% (5m) | Auto-scale tile cache nodes |
| Metadata sync latency | < 15 min | > 20 min | Trigger catalog reconciliation job |
| Vector query p95 | < 450 ms | > 600 ms | Optimize spatial indexes, verify CRS alignment |
| Policy evaluation time | < 5 ms | > 15 ms | Audit Rego complexity, cache compiled policies |
| Deprecation window honored | 100% | Any early archival | Halt archival job, restore read route |
To diagnose an SLA breach, correlate spatial_tile_latency_seconds with opa_evaluation_duration_seconds — high latency in both points to a gateway policy misconfiguration. Confirm the declared manifest schema matches the live tile or vector payload via the contract validation pipeline, then apply automated scaling through a Horizontal Pod Autoscaler with custom metrics. If breaches persist beyond 15 minutes, trigger circuit-breaker routing to a fallback static tileset and notify the domain stewards.
Governance & Compliance Notes
Lifecycle transitions are governance events and must leave an audit trail. Every promotion, deprecation, and archival should emit an immutable record capturing the actor, the source and target version strings, the CRS and resolution, and the Cosign signature digest, so a product’s full provenance is reconstructable from the catalog alone. Policy-as-code hooks run at two points: the admission controller blocks any transition whose manifest fails schema or topology validation, and the gateway Rego policy blocks any read that falls outside the product’s declared extent or CRS allowlist. Both hooks reference the same scoping contract, which keeps governance consistent between publication time and query time.
Jurisdictional constraints frequently shape archival and deletion. A product carrying regulated spatial data — cadastral boundaries, critical-infrastructure footprints, or personally locating telemetry — may have a minimum retention period that prevents early archival, or a data-residency rule that forbids restoring an archived artifact into a different region’s compute plane. Encode these as policy fields on the manifest so the lifecycle controller enforces them automatically rather than relying on operator discipline. For authoritative interoperability standards consult the OGC API - Features specification, and for policy-as-code implementation patterns reference the Open Policy Agent Documentation.
Related
- Up: Geospatial Data Mesh Fundamentals — the parent reference for this architecture
- Spatial Domain Boundary Design — decoupling spatial domains the lifecycle binds versions to
- Scoping Rules for Spatial Products — the publication gates a transition must clear
- Metadata Cataloging for Raster/Vector — the federated catalog that records lifecycle state
- Product Thinking for GIS Datasets — why spatial assets are managed as products