Octopus CRDs
The Octopus CRDs live in the API group gateway.octopus.io, version v1alpha1, and are all
namespaced. They expose Octopus-native features (auth providers, plugin chains, rate limiting,
Rhai scripting, subdomain conventions) that the portable Gateway API does not model. Install them
with octopus crd | kubectl apply -f - or the vendored bundle — see
Install.
| Kind | Short name | Purpose |
OctopusGateway | ogw | A logical Octopus gateway instance (listen address, class, default auth). |
OctopusRoute | ort | A full-fidelity route with auth/rate-limit/plugins/scripting. |
OctopusUpstream | oup | An upstream cluster with explicit targets and an LB strategy. |
OctopusPolicy | opol | A GEP-713 policy overlay attaching behavior onto another resource. |
OctopusGateway01
OctopusGateway is a virtual gateway: a named scope that binds a set of hostnames, groups the
routes under them, and pushes inherited policy defaults down to its child routes. See
Virtual gateways for the full model (convention path-split,
isolation tiers, FARP binding).
| Field | Type | Default | Description |
listen | string | (required) | Listen address, e.g. 0.0.0.0:8080. |
gatewayClassName | string | (unset) | The GatewayClass this gateway serves. |
defaultAuthProvider | string | (unset) | Default auth provider (superseded by defaultPolicy.authProvider). |
hostnames | string[] | [] | Hostnames this gateway owns (exact api.x.com or wildcard *.x.com). A route whose host falls in this set attaches here and inherits defaultPolicy. Empty = match any host. |
defaultPolicy | object | (unset) | Defaults inherited by attached routes: authProvider, timeoutSeconds, rateLimit, cors. An explicit value on a route always wins. |
isolation | enum | shared | shared (in-process partition of the edge) or dedicated (its own directly-reachable Octopus deployment). |
farpBinding | bool | false | When true, FARP-discovered services are served under this gateway's hostnames and inherit its policy. |
apiVersion: gateway.octopus.io/v1alpha1
kind: OctopusGateway
metadata:
name: platform-api
namespace: octopus-system
spec:
listen: "0.0.0.0:8080"
gatewayClassName: octopus
hostnames: ["api.example.cloud"]
isolation: shared
farpBinding: true
defaultPolicy:
authProvider: jwt
timeoutSeconds: 30
cors:
allowedOrigins: ["https://app.example.cloud"]
allowedMethods: ["GET", "POST"]
allowCredentials: true
maxAge: 600OctopusRoute02
A full route. The path is used as-is as a native router pattern (it supports :param and
*wildcard), and upstream references an OctopusUpstream by name (or a
discovered service). One route is produced per method.
| Field | Type | Default | Description |
parentRefs | string[] | [] | Names of OctopusGateway/Gateway resources this route attaches to. |
path | string | (required) | Match path; supports :param and *wildcard. |
methods | string[] | [] | HTTP methods matched. Empty expands to GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS. |
upstream | string | (required) | Target upstream (an OctopusUpstream name or discovered service). |
priority | int32 | 0 | Higher wins on identical path collisions. |
stripPrefix | string | (unset) | Strip this prefix before proxying. |
addPrefix | string | (unset) | Add this prefix before proxying. |
authProvider | string | (unset) | Named auth provider to enforce. |
skipAuth | bool | false | Skip authentication for this route. |
requireRoles | string[] | [] | Required roles. |
requireScopes | string[] | [] | Required scopes. |
authzRule | string | (unset) | Authorization rule expression. |
timeoutSeconds | uint64 | (unset) | Per-route timeout (seconds). |
rateLimit | object | (unset) | Token-bucket rate limit: requests, windowSeconds. |
plugins | string[] | [] | Ordered plugin chain (plugin ids). |
scriptRef | string | (unset) | Reference to a Rhai script (e.g. a ConfigMap name). |
convention | object | (unset) | Host-to-backend convention (subdomain routing) — see below. |
apiVersion: gateway.octopus.io/v1alpha1
kind: OctopusRoute
metadata:
name: orders
namespace: shop
spec:
parentRefs: ["edge"]
path: /orders
methods: ["GET", "POST"]
upstream: orders-up
priority: 5
stripPrefix: /orders
authProvider: jwt
requireScopes: ["orders:read"]
timeoutSeconds: 30
rateLimit:
requests: 100
windowSeconds: 60
plugins: ["request-id"]Convention (subdomain routing)
When convention is set, the route becomes a single wildcard-host route (*.<baseDomain>) whose
backend is derived per request from the host — instead of declaring a route per tenant.
| Field | Type | Default | Description |
baseDomain | string | (required) | Base domain; the route matches *.<baseDomain>. |
layout | string[] | (required) | Label roles for the tenant prefix, left to right: service, namespace (alias tenant), or ignore. |
defaultService | string | (unset) | Service name when layout has no service entry. |
port | uint16 | 80 | Upstream port for the derived Service. |
script | string | (unset) | Inline Rhai script mapping host → #{namespace, service[, port]}, overriding layout when it returns a mapping. |
scriptRef | object | (unset) | Load the host-resolution script from a ConfigMap (name, key, optional namespace); ignored when script is set. Cross-namespace refs require a ReferenceGrant. |
backendStrategy | string | ServiceDNS | ServiceDNS routes to the cluster Service DNS name; EndpointSlice balances across Pod IPs directly. |
apiVersion: gateway.octopus.io/v1alpha1
kind: OctopusRoute
metadata:
name: tenants
namespace: default
spec:
path: /*rest
methods: ["GET"]
upstream: unused # ignored when a convention derives the backend
convention:
baseDomain: platform.com
layout: ["service", "namespace"] # orders.acme.platform.com → svc `orders` in ns `acme`
port: 8080
backendStrategy: ServiceDNSA convention's scriptRef is resolved from a ConfigMap. Same-namespace refs work directly; a
cross-namespace ref requires a ReferenceGrant (kind OctopusRoute, group gateway.octopus.io)
in the ConfigMap's namespace permitting access to ConfigMap. An inline script always wins over
a scriptRef.
OctopusUpstream03
An explicit upstream cluster, referenced by name from OctopusRoute.upstream.
| Field | Type | Default | Description |
targets | object[] | [] | Targets: host, port, optional weight (default 1). |
lbStrategy | string | round_robin | One of round_robin, least_conn/least_connections, weighted/weighted_round_robin, random, ip_hash. |
apiVersion: gateway.octopus.io/v1alpha1
kind: OctopusUpstream
metadata:
name: orders-up
namespace: shop
spec:
lbStrategy: least_conn
targets:
- host: 10.0.0.1
port: 8080
weight: 3
- host: 10.0.0.2
port: 8080OctopusPolicy04
OctopusPolicy is a GEP-713 policy attachment: it never creates routes, it enriches the
routes produced by the resource it targets via targetRef. With overrideRoute: true it overrides
the target's inline settings; otherwise it only fills gaps ("default" semantics).
| Field | Type | Default | Description |
targetRef | object | (required) | The resource to attach to: group, kind, name, optional sectionName. |
authProvider | string | (unset) | Auth provider to enforce on the target's routes. |
plugins | string[] | [] | Ordered plugin chain to apply. |
rateLimit | object | (unset) | Rate limit to apply (requests, windowSeconds). |
scriptRef | string | (unset) | Reference to a Rhai script. |
overrideRoute | bool | false | true overrides route-inline settings; default only fills gaps. |
Supported targetRef.kind values are HTTPRoute, GRPCRoute (both in group
gateway.networking.k8s.io), and OctopusRoute (group gateway.octopus.io). A policy targets
routes in its own namespace. Other kinds are ignored.
apiVersion: gateway.octopus.io/v1alpha1
kind: OctopusPolicy
metadata:
name: orders-auth
namespace: shop
spec:
targetRef:
group: gateway.networking.k8s.io
kind: HTTPRoute
name: api-route
authProvider: jwt
rateLimit:
requests: 100
windowSeconds: 60
overrideRoute: falseThe overlay currently applies authProvider and rateLimit to the targeted routes. plugins and
scriptRef are accepted on the spec but are not yet applied by the overlay — prefer setting those
inline on an OctopusRoute for now.
Reconciling alongside Gateway API05
Octopus CRDs and Gateway API resources are translated into the same intermediate route table and
merged into one live router (alongside your static config). A common pattern: define portable routing
with HTTPRoute/GRPCRoute, then layer Octopus-specific behavior onto those routes with an
OctopusPolicy. Or skip the Gateway API entirely and use OctopusRoute + OctopusUpstream for
full-fidelity Octopus routing. See Operator for the merge and precedence
model and Gateway API for the Gateway API field mappings.