Security
Octopus secures traffic at three layers: authentication (who is calling), authorization (what they may do), and transport security (TLS/mTLS). Each is configured declaratively and applied globally or per route by a single auth-gateway middleware.
How the three layers fit together01
A request passes through the auth-gateway middleware once, in this order:
Authentication — a named provider inspects the request (a token, an API key, a client certificate, or an external service) and produces an authenticated principal (id, roles, scopes), or rejects the request.
Authorization — the principal is checked against the matched route's role/scope requirements and any Rhai rule, then against global authorization rules (Rhai or OPA).
Transport security — TLS is terminated on the listener before any of this; mutual TLS can additionally require and verify a client certificate at the handshake.
Only one auth-gateway middleware runs, and it is added to the chain only when at least one provider
is declared under auth_providers, or when auth.global_enforce is true. If neither is the case,
no authentication or authorization is performed.
Authentication02
Authentication providers are declared once under auth_providers (a map keyed by provider name) and
referenced by name. A request is authenticated by one provider — the one its matched route
selects via auth_provider, falling back to the global auth.default_provider. Routes may opt out
entirely with skip_auth: true, and global auth.skip_paths patterns bypass auth before any
provider runs. Supported provider types (the type: tag, snake_case):
jwt— validate bearer tokens against a static secret or public key, checking issuer, audience, and expiry.oidc— discover an OpenID Connect provider, refresh its JWKS in the background, and validate tokens against the published keys.api_key— match a key presented in a header or query parameter against a static key list.forward_auth— delegate the decision to an external HTTP service.mtls— derive the principal from a verified client certificate's Common Name.
Octopus selects a single provider per request — it does not try multiple providers in sequence.
The oidc provider's fallback_provider field is parsed but not currently wired (see
OIDC).
Authorization03
Once a caller is authenticated, authorization decides whether the request is allowed. The matched
route can require roles (any-of) and scopes (all-of), and carry a custom Rhai expression
(authz_rule). Beyond the route, global rules in auth.authz run through the embedded Rhai
engine or an external OPA server. See Authorization for exactly
what each engine evaluates.
Transport security (TLS)04
Octopus terminates TLS on its listener when gateway.tls is set, supports mutual TLS to
authenticate clients by certificate, and hot-reloads file-based certificates. On Kubernetes,
certificates can instead be sourced from Gateway listener Secrets (for example, issued by
cert-manager) and swapped without dropping connections. See TLS.