Skip to content

Latest commit

 

History

History
126 lines (98 loc) · 5.74 KB

File metadata and controls

126 lines (98 loc) · 5.74 KB

Security model and deployment expectations

MARS does not implement authentication. It must be deployed behind a reverse proxy or ingress that terminates TLS and enforces request authentication. Exposing the MARS HTTP listener directly to a public network is unsafe.

This document describes what MARS provides, what it explicitly does not provide, and the deployment patterns that close the gap.

What MARS does NOT provide

  • Authentication. MARS accepts every well-formed HTTP request. There is no API key check, no session validation, no OAuth/OIDC integration, no mTLS verification at the application layer.
  • TLS termination. The MARS HTTP listener binds plaintext. There is no configuration option to load a certificate; this is intentional. TLS belongs at the ingress so certificate rotation, OCSP stapling, ciphersuite policy, and ALPN are all owned by the platform layer.
  • Authorisation per user. MARS has no concept of an authenticated principal. It cannot make a "user X is allowed layer Y" decision because it never sees user identity.
  • Rate limiting per user / per tenant. MARS has no user identity, so any rate limit must be applied upstream.

What MARS DOES provide

  • Per-layer service-operation gating. Each layer's ows.request_gating can disable specific service operations (e.g. forbid WmsGetFeatureInfo for a given layer). This is access control, not authentication: it restricts which surface MARS will serve for that layer to any caller that reaches it. If the listener is reachable, the gated subset is reachable.
  • CIDR-based trust for forwarded headers. service.forwarded_headers_trust decides which TCP peers MARS believes when they assert Forwarded / X-Forwarded-*. This is integrity for capabilities-URL synthesis, not authentication of end users.
  • Health and metrics endpoints. /healthz, /readyz, and /metrics are unauthenticated by design (kubelet, Prometheus, etc.). The pprof debug listener, when enabled, refuses non-loopback binds unless an explicit opt-in is set (see observability.debug_pprof_listen and observability.debug_pprof_allow_non_loopback).

The distinction is load-bearing: ServiceOp gating decides which operations a layer exposes; it does not decide who may invoke them.

Recommended deployment patterns

All of the following sit in front of MARS and own TLS termination, authentication, and per-request authorisation. Pick one based on the rest of your platform.

Ingress + oauth2-proxy (OIDC / OAuth)

A typical pattern for Kubernetes:

  1. Ingress controller (Traefik, Nginx, Envoy/Istio, HAProxy, ...) terminates TLS.
  2. oauth2-proxy sits between the ingress and the MARS Service, exchanging the upstream cookie / bearer token for a verified upstream identity.
  3. The ingress only forwards requests to MARS after oauth2-proxy has authenticated the caller.

The MARS layer continues to honour forwarded headers from the trusted ingress peer for capabilities-URL synthesis. See ingress.md for the forwarded-headers trust policy.

Ingress with native OIDC

Some ingress controllers (Traefik with the OIDC middleware plugin, Envoy / Istio with the JWT authentication filter, Nginx with auth_request) can validate OIDC tokens directly without an intermediate sidecar. Same shape as above, fewer moving parts.

mTLS at the ingress

If clients are machine-to-machine (sister services, harvesters, parity suites), mutual TLS at the ingress provides identity without the OIDC flow. The ingress terminates client TLS, verifies the client certificate against a trusted CA, and forwards the plaintext request to MARS. The downstream identity (client CN, SAN) can be passed via X-Forwarded-Client-Cert or similar for audit logging.

API gateway

Any API gateway (Kong, Ambassador, AWS API Gateway, Azure APIM, GCP API Gateway) that can terminate TLS, validate credentials, and forward an authenticated request fits the same pattern. MARS is the upstream service; the gateway is the auth boundary.

Network policy / private network

For internal-only deployments (compiler-side, batch consumers, intra-cluster service mesh), network policy can be the auth boundary. MARS still must not listen on a publicly routable address; the cluster network policy must ensure only authorised peers can reach the listener.

Verifying your deployment

After deploying behind an ingress, confirm:

  1. MARS is not reachable directly. A request to the MARS pod IP or the cluster-internal Service from outside the cluster should fail or never arrive. If MARS is reachable, the ingress is being bypassed.
  2. TLS is enforced at the ingress. A plaintext request to the public hostname should redirect to HTTPS or refuse.
  3. Unauthenticated requests are refused. A curl https://maps.example/wms without credentials should be denied by the ingress before reaching MARS.
  4. MARS sees the correct public URL. GET /status (returned through the ingress) reports the public hostname and scheme. See ingress.md for the forwarded-headers configuration.

Why MARS does not implement authentication

Auth is a deployment concern, not a rendering concern. Embedding it in MARS would require:

  • Choosing one (or a small set) of identity providers and token formats, forcing operators to use them or work around them.
  • Implementing session management, token validation, and credential storage - all areas where industry-standard tooling (oauth2-proxy, ingress filters, API gateways) is more mature and audited.
  • Coupling MARS releases to security advisories in those tools.

By delegating auth to the platform, MARS stays a rendering service and the platform owns the security boundary it is already configured to own.