Skip to content

Kubernetes operator

The OrbitalReg Kubernetes operator manages the entire governance surface from CRDs in your GitOps repo. Projects, repositories, service accounts and tokens, retention policies, security blocks, and webhook subscriptions — all seven resources are reconciled against the OrbitalReg REST API by an in-cluster controller.

The operator's source repo is tools/k8s-operator/. The Helm chart lives at tools/k8s-operator/charts/orbitalreg-operator.

This section is the externally-rendered companion to docs/operator/ in the repo. The in-repo tree remains the canonical engineering source.

When to use it

  • You have more than a handful of projects and clicking through the admin UI no longer scales.
  • You manage your platform via GitOps (ArgoCD, Flux) and want the same flow for OrbitalReg state.
  • You need per-namespace credential provisioning — the operator materialises service-account tokens into Kubernetes Secrets in the consuming namespace, no human-readable token ever touches a CI variable.

When NOT to use it

  • You already use the Terraform provider for the same resources. Pick one or the other for any given resource — overlapping management causes write-write loops.
  • You only have one or two projects and your team is fluent with the admin UI. The operator's value scales with inventory.

CRDs

CRDScopePurpose
OrbitalRegProjectCluster-scopedTop-level governance boundary
OrbitalRegRepositoryCluster-scopedTyped package store
OrbitalRegServiceAccountCluster-scopedNon-human principal
OrbitalRegServiceAccountTokenNamespaceBearer-token credential, materialised into Secret
OrbitalRegRetentionPolicyCluster-scopedPer-repo prune rules
OrbitalRegSecurityBlockCluster-scopedPattern-match block rules
OrbitalRegWebhookSubscriptionCluster-scopedOutbound HMAC-signed event delivery

Full schemas and field-by-field descriptions: CRD reference.

Reconciliation model

Each controller follows the same loop:

  1. Resolve refsspec.projectRef, spec.repositoryRef, etc. to the parent CR's status.<id>.
  2. Adopt or create — first reconcile pass either takes ownership of an existing upstream row (matched by deterministic key) or POSTs a new one.
  3. PATCH on drift — subsequent passes compute a state→plan diff and PATCH only fields that actually changed. UI edits made in between passes are reverted.
  4. Finalizer-guarded delete — deleting the CR triggers a foreground-cascade DELETE on the upstream row, then removes the finalizer.

The reconcile interval defaults to 5 minutes; tune via the manager's --reconcile-period flag.

Status conditions

Every CR carries two conditions:

  • Synced — the controller's view; True once the upstream row matches the CR's spec, False with a reason of CreateFailed, UpdateFailed, or RefUnresolved.
  • Ready — the canonical Kubernetes name; mirrors Synced's value but in the shape that kubectl wait --for=condition=Ready, ArgoCD, Lens, and k9s expect.

status.observedGeneration advances even on no-op merges so kubectl wait honours observedGeneration semantics.

Where to next

Released under the Apache-2.0 License.