zitadel-operator

module
v0.19.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 23, 2026 License: MIT

README

Zitadel Operator

CI Release Go Report Card

A Kubernetes operator that manages Zitadel resources declaratively through Custom Resource Definitions — organizations, projects, OIDC/API/SAML applications, users, grants, policies, identity providers, and notification providers. Works with Zitadel Cloud and self-hosted instances.

Why

  • GitOps for identity — applications declare their own OIDC clients and service accounts next to their Deployments; credentials land in Kubernetes Secrets.
  • Explicit, fail-closed multi-tenancyScopeMap objects route tenant namespaces to Zitadel org/project scopes, and each scope is reconciled with an internally minted, scope-limited credential (internal delegation). A namespace that matches no rule is rejected, not defaulted.
  • Single writer with drift detection — within a managed scope the operator owns the resources it declares: out-of-band edits are detected and reverted on the next reconcile.
  • 43 CRDs with structured Ready conditions, finalizer-based cleanup, idempotent reconciliation (no hot loops), and Server-Side Apply status writes that coexist with other controllers.

Quickstart

# 1. Install the CRDs (cluster-scoped, install once)
helm install zitadel-operator-crds oci://ghcr.io/truvity/charts/zitadel-operator-crds

# 2. Create the credential Secret (JWT key of a Zitadel service account)
kubectl -n zitadel-operator create secret generic zitadel-admin-sa \
  --from-file=zitadel-admin-sa.json=/path/to/key.json

# 3. Install the operator
helm install zitadel-operator oci://ghcr.io/truvity/charts/zitadel-operator \
  --namespace zitadel-operator --create-namespace \
  --set config.domain=auth.example.com \
  --set config.binding=iam-owner \
  --set credentials.secretName=zitadel-admin-sa

Then declare an application:

apiVersion: zitadel.truvity.io/v1alpha2
kind: OIDCApp
metadata:
  name: argocd
  namespace: argocd
spec:
  projectId: "376393790358824134"
  type: confidential
  authMethod: basic
  redirectUris:
    - https://argocd.example.com/auth/callback
  secretRef:
    name: argocd-oidc

The operator creates the application in Zitadel and writes client_id + client_secret into the argocd-oidc Secret. See the Helm installation guide for the full walk-through, including the binding choice (iam-owner vs org-owner) that determines what the operator can manage.

Documentation

Section Contents
Install Helm installation · Deployment shapes (recommended: the fleet) · Configuration reference · Binding levels: iam-owner vs org-owner
Operations Multi-operator topologies · Scope-map administration & delegation · Dual-serving one namespace · Large multi-tenant installations · Metrics · Troubleshooting
Architecture Resource hierarchy & CRD map · Scope resolution · Internal delegation & credential lifecycle · Dual-serving semantics · Status conditions & SSA
Reference CRD API reference (generated from the Go types)
Development Contributing · Repository layout · Integration-test architecture
History Changelog · Migration v0.17 → v0.18 · Design records · Research notes

Resource model at a glance

Zitadel instance          ← operator deployment config (domain + binding), not a CRD
└── Organization          ← Organization CR, or a pre-existing org routed via scope maps
    ├── Project           ← Project CR (inline roles)
    │   ├── OIDCApp / APIApp / SAMLApp / ApplicationKey
    │   └── ProjectMember / ProjectGrant / ProjectGrantMember
    ├── MachineUser / HumanUser / PersonalAccessToken / UserGrant / OrgMember
    ├── IdentityProvider / org-scoped policies / MessageText / Domain / OrgMetadata
    └── (instance level) Default* policies, GoogleIdP/GitHubIdP, Email/SmsProvider,
        ActionTarget/ActionExecution, InstanceMember, DefaultMessageText

All CRDs are namespaced; namespaces are the RBAC and tenancy boundary. The full catalog with permission requirements lives in Resource hierarchy; every spec/status field is documented in the API reference.

Key invariants

  • One operator = one Zitadel instance = one credential, asserted at startup (binding: iam-owner | org-owner, verified against the credential's real memberships — mismatch crashes before any reconcile).
  • Routing authority lives with the operator, never with the routed tenant: scope maps are admin-controlled objects in the operator's namespace; namespace labels are facts the maps interpret.
  • The binding credential only mints, rotates, and revokes delegated service accounts; tenant resources are reconciled with the scope-limited delegate key.
  • Zero scope maps = passthrough: without any ScopeMap, the operator reconciles directly with the binding credential (the pre-v0.18 behavior), so installing the CRD is not a flag day.

License

MIT

Directories

Path Synopsis
api
v1alpha2
Package v1alpha2 contains API Schema definitions for the zitadel.truvity.io v1alpha2 API group.
Package v1alpha2 contains API Schema definitions for the zitadel.truvity.io v1alpha2 API group.
cmd
operator command
internal
config
Package config loads the operator configuration from a YAML file.
Package config loads the operator configuration from a YAML file.
controller
Package controller implements Kubernetes controllers for Zitadel resources.
Package controller implements Kubernetes controllers for Zitadel resources.
delegation
Package delegation mints and caches per-scope Zitadel machine users ("delegates") and hands out Zitadel clients authenticated as them.
Package delegation mints and caches per-scope Zitadel machine users ("delegates") and hands out Zitadel clients authenticated as them.
scopemap
Package scopemap resolves tenant namespaces to Zitadel org/project scopes via ScopeMap CRs living in the operator's namespace.
Package scopemap resolves tenant namespaces to Zitadel org/project scopes via ScopeMap CRs living in the operator's namespace.
zitadel
Package zitadel provides a client wrapper around the official zitadel-go SDK for use by the operator controllers.
Package zitadel provides a client wrapper around the official zitadel-go SDK for use by the operator controllers.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL