Octopus
1.x
Docs/Octopus/Octopus CRDs
Open

Reading7 min
Updated31 Jul 2026
Sourcev1/kubernetes/octopus-crds.mdx

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.

KindShort namePurpose
OctopusGatewayogwA logical Octopus gateway instance (listen address, class, default auth).
OctopusRouteortA full-fidelity route with auth/rate-limit/plugins/scripting.
OctopusUpstreamoupAn upstream cluster with explicit targets and an LB strategy.
OctopusPolicyopolA 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).

FieldTypeDefaultDescription
listenstring(required)Listen address, e.g. 0.0.0.0:8080.
gatewayClassNamestring(unset)The GatewayClass this gateway serves.
defaultAuthProviderstring(unset)Default auth provider (superseded by defaultPolicy.authProvider).
hostnamesstring[][]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.
defaultPolicyobject(unset)Defaults inherited by attached routes: authProvider, timeoutSeconds, rateLimit, cors. An explicit value on a route always wins.
isolationenumsharedshared (in-process partition of the edge) or dedicated (its own directly-reachable Octopus deployment).
farpBindingboolfalseWhen 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: 600

OctopusRoute02

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.

FieldTypeDefaultDescription
parentRefsstring[][]Names of OctopusGateway/Gateway resources this route attaches to.
pathstring(required)Match path; supports :param and *wildcard.
methodsstring[][]HTTP methods matched. Empty expands to GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS.
upstreamstring(required)Target upstream (an OctopusUpstream name or discovered service).
priorityint320Higher wins on identical path collisions.
stripPrefixstring(unset)Strip this prefix before proxying.
addPrefixstring(unset)Add this prefix before proxying.
authProviderstring(unset)Named auth provider to enforce.
skipAuthboolfalseSkip authentication for this route.
requireRolesstring[][]Required roles.
requireScopesstring[][]Required scopes.
authzRulestring(unset)Authorization rule expression.
timeoutSecondsuint64(unset)Per-route timeout (seconds).
rateLimitobject(unset)Token-bucket rate limit: requests, windowSeconds.
pluginsstring[][]Ordered plugin chain (plugin ids).
scriptRefstring(unset)Reference to a Rhai script (e.g. a ConfigMap name).
conventionobject(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.

FieldTypeDefaultDescription
baseDomainstring(required)Base domain; the route matches *.<baseDomain>.
layoutstring[](required)Label roles for the tenant prefix, left to right: service, namespace (alias tenant), or ignore.
defaultServicestring(unset)Service name when layout has no service entry.
portuint1680Upstream port for the derived Service.
scriptstring(unset)Inline Rhai script mapping host#{namespace, service[, port]}, overriding layout when it returns a mapping.
scriptRefobject(unset)Load the host-resolution script from a ConfigMap (name, key, optional namespace); ignored when script is set. Cross-namespace refs require a ReferenceGrant.
backendStrategystringServiceDNSServiceDNS 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: ServiceDNS
Note

A 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.

FieldTypeDefaultDescription
targetsobject[][]Targets: host, port, optional weight (default 1).
lbStrategystringround_robinOne 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: 8080

OctopusPolicy04

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).

FieldTypeDefaultDescription
targetRefobject(required)The resource to attach to: group, kind, name, optional sectionName.
authProviderstring(unset)Auth provider to enforce on the target's routes.
pluginsstring[][]Ordered plugin chain to apply.
rateLimitobject(unset)Rate limit to apply (requests, windowSeconds).
scriptRefstring(unset)Reference to a Rhai script.
overrideRouteboolfalsetrue 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: false
Warning

The 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.