Kubernetes Operator

The Tetrapus Operator is a kube-rs Controller that turns three Custom Resource kinds into the actual Kubernetes objects a tenant needs. It is the canonical way to provision pod-per-Org Tetrapus on a cluster you own.

Provisioning flow

graph TD KCTL["kubectl apply -f org.yaml"] --> API["Kube API server"] API --> OP["tetrapus-operator<br/>(Controller)"] OP --> RECONCILE["reconcile_org()"] RECONCILE --> PVC["PersistentVolumeClaim<br/>(unless external_db_url)"] RECONCILE --> SECRET["Secret<br/>(bootstrap admin + DB url)"] RECONCILE --> SVC["Service<br/>org-acme"] RECONCILE --> DEP["Deployment<br/>data_plane_image"] DEP --> POD["Pod ready"] OP -.->|status.phase = Running| API

Custom Resource Definitions

Org

A single tenant's pod-per-Org descriptor.

YAML
apiVersion: tetrapus.io/v1alpha1
kind: Org
metadata:
  name: acme
  namespace: tenants
spec:
  slug: acme
  region_code: us-east-1
  plan_tier: enterprise
  data_plane_image: tetrapus/server:1.0.0
  data_plane_resources:
    cpu_request: "500m"
    cpu_limit:   "2"
    memory_request: "512Mi"
    memory_limit:   "4Gi"
  external_db_url: null   # null = provision a sqlite PVC instead

TenantPlane

A shared multi-tenant Deployment that serves up to max_orgs tenants — lighter-weight tier for free / team plans.

YAML
apiVersion: tetrapus.io/v1alpha1
kind: TenantPlane
metadata:
  name: shared-eu
spec:
  region_code: eu-west-1
  data_plane_image: tetrapus/server:1.0.0
  max_orgs: 50
  replicas: 3

KeyMaterial

A typed pointer to JWT signing-key material in a KMS. The operator validates the URI scheme but never reads the key — the data plane resolves it at startup.

YAML
apiVersion: tetrapus.io/v1alpha1
kind: KeyMaterial
metadata:
  name: acme-jwt
spec:
  org_ref: tenants/acme
  kms_uri: aws-kms:arn:aws:kms:us-east-1:123:key/abcd-...
  kid: 2026-04-jwt

Reconciler behaviour

  • Creates a PersistentVolumeClaim sized per plan tier only if external_db_url is empty.
  • Creates a Secret with bootstrap admin email and database URL.
  • Creates a Service (ClusterIP) named org-<slug>.
  • Creates a Deployment running the chosen data_plane_image with the requested resource block.
  • Updates status.phase through Pending → Provisioned → Running.
  • On delete: cascades down via ownerReferences; PVCs are retained unless --purge-pvc is set.

RBAC

The operator needs cluster-scoped CRD privileges plus full namespace privileges in the watched namespace. The Helm chart provisions a ClusterRole with:

YAML
rules:
  - apiGroups: ["tetrapus.io"]
    resources: ["orgs", "tenantplanes", "keymaterials",
                "orgs/status", "tenantplanes/status", "keymaterials/status"]
    verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
  - apiGroups: ["apps"]
    resources: ["deployments"]
    verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
  - apiGroups: [""]
    resources: ["services", "secrets", "persistentvolumeclaims"]
    verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
  - apiGroups: ["apiextensions.k8s.io"]
    resources: ["customresourcedefinitions"]
    verbs: ["get", "list", "watch"]

Related

Questions?

Reach out for help with integration, deployment, or custom domain codecs.