Self-service application onboarding for GitOps-friendly Kubernetes platforms.
One CRD to rule
routing, TLS, SSO, and landing-page registration — all continuously reconciled.
What is it? · How it works · Features · Installation · Usage · Development · Docs · Contributing
Status: Under active development as part of Nebari Infrastructure Core (NIC). APIs and behavior may change without notice.
The Nebari Operator is a Kubernetes controller that enables self-service application onboarding in GitOps-friendly
clusters. When a team deploys an app via Helm or Argo CD, they declare a single NebariApp custom resource — the
operator takes care of the rest:
- HTTP/HTTPS Routes — Gateway API
HTTPRoutecreated and maintained automatically - TLS Termination — cert-manager
Certificateprovisioned on demand - SSO Authentication — OIDC
SecurityPolicywired to Keycloak, including automatic client provisioning - Landing Page Registration — service metadata surfaced to Nebari Landing with visibility controls
No more hand-crafting Gateway, HTTPRoute, SecurityPolicy, or Keycloak clients. Declare intent; the operator
reconciles reality.
The operator runs a pipeline of focused reconcilers, each responsible for one concern:
NebariApp CR
│
├─► Validation Reconciler — namespace opt-in, service existence
├─► Routing Reconciler — HTTPRoute + TLS Certificate
├─► Auth Reconciler — OIDC SecurityPolicy + Keycloak client
└─► Landing Page Reconciler — registration in nebari-landing cache
Each reconciler is independent, updates status.conditions, and emits Kubernetes Events for full observability. The
control loop is continuously reconciled — drift from desired state is corrected automatically.
Learn more: Reconciler Architecture
| Feature | Description |
|---|---|
| Declarative Configuration | One NebariApp CRD defines routing, TLS, auth, and landing-page visibility |
| Automatic Route Generation | HTTPRoute resources are created and kept in sync automatically |
| TLS Management | Seamless cert-manager integration — certificates provisioned and renewed hands-free |
| OIDC Authentication | Optional SSO via Keycloak, with automatic SecurityPolicy and client provisioning |
| Public Route Bypass | Per-path auth bypass for health-check and callback endpoints |
| Landing Page Integration | Surfaces apps to nebari-landing with category, icon, and visibility controls |
| GitOps Compatible | Continuously reconciled — desired state is always enforced |
| Multi-Platform | Works with any Kubernetes (cloud, on-prem, local kind/minikube) |
| Namespace Isolation | Opt-in per namespace via label — no accidental adoption |
Install the latest stable release with a single command:
kubectl apply -f https://github.com/nebari-dev/nebari-operator/releases/latest/download/install.yamlVERSION=v0.1.0
kubectl apply -f https://github.com/nebari-dev/nebari-operator/releases/download/${VERSION}/install.yamlhelm upgrade --install nebari-operator \
oci://ghcr.io/nebari-dev/charts/nebari-operator \
--namespace nebari-operator-system \
--create-namespacekubectl get pods -n nebari-operator-system
kubectl logs -n nebari-operator-system -l control-plane=controller-managerMulti-arch images (amd64 / arm64) are published to Quay.io on every release:
quay.io/nebari/nebari-operator:latest
quay.io/nebari/nebari-operator:v0.1.0
quay.io/nebari/nebari-operator:main
Opt your namespace in and create a NebariApp to expose a service:
# Opt the namespace into operator management
kubectl label namespace my-team nebari.dev/managed=trueapiVersion: reconcilers.nebari.dev/v1
kind: NebariApp
metadata:
name: my-app
namespace: my-team
spec:
hostname: my-app.example.com
service:
name: my-service
port: 8080
routing:
tls:
enabled: true
routes:
- pathPrefix: /
publicRoutes:
- pathPrefix: /healthz
pathType: Exact
auth:
enabled: true
provider: keycloak
provisionClient: true
landingPage:
enabled: true
displayName: "My App"
description: "A great internal tool"
category: "Engineering"
icon: "tool"
visibility: authenticatedThe operator will automatically create:
HTTPRoute— routesmy-app.example.comtraffic tomy-service:8080Certificate— cert-manager certificate for TLSSecurityPolicy— OIDC authentication enforced at the gateway- Keycloak Client — OIDC client provisioned in the configured realm
- Landing Page Entry — app surfaced in nebari-landing for authenticated users
See the Configuration Reference for all available options.
| Tool | Version | Notes |
|---|---|---|
go |
1.25+ | Controller and tests |
docker or podman |
24+ | Image builds |
kubectl |
1.28+ | Cluster interaction |
make |
any | Build automation |
| Kubernetes cluster | 1.28+ | kind, minikube, or cloud |
# Regenerate CRDs and deep-copy code after API changes
make manifests generate
# Run unit tests
make test
# Run linter
make lint
# Run the operator locally against your current cluster
make run# Create a Kind cluster with the full Nebari infrastructure stack
cd dev && make setup
# Build and load the operator image
cd ..
make docker-build IMG=quay.io/nebari/nebari-operator:dev
kind load docker-image quay.io/nebari/nebari-operator:dev --name nebari-operator-dev
# Install CRDs and deploy
make install deploy IMG=quay.io/nebari/nebari-operator:dev
# Deploy the example app and NebariApp CR
kubectl apply -f dev/examples/app-deployment.yaml
kubectl apply -f dev/examples/nebariapp.yaml
# Iterate: rebuild and roll out
make docker-build IMG=quay.io/nebari/nebari-operator:dev
kind load docker-image quay.io/nebari/nebari-operator:dev --name nebari-operator-dev
kubectl rollout restart deployment nebari-operator-controller-manager -n nebari-operator-system
# Tear down
cd dev && make teardownSee dev/README.md for the full local development guide.
make help # List all available targets with descriptions
make fmt # Format code (go fmt)
make vet # Run static analysis (go vet)
make test # Run unit tests
make test-e2e # Run end-to-end tests (requires a live cluster)
make lint # Run golangci-lint
make build # Build the manager binary
make docker-build # Build the Docker image
make deploy # Deploy to the current cluster
make generate-dev # Shortcut: manifests + generate (after API changes)See the Makefile Reference for the complete target list.
# Tag and push from main
git checkout main && git pull origin main
git tag -a v1.0.0 -m "Release v1.0.0"
git push origin v1.0.0
# Create the GitHub release — CI takes it from here
gh release create v1.0.0 --generate-notesCI automatically: runs tests · builds multi-arch images · packages the Helm chart · generates install.yaml · uploads
all artifacts.
See docs/maintainers/release-checklist.md for the complete process.
- Quick Start Guide — Install and deploy your first app in 5 minutes
- Configuration Reference — Complete
NebariAppCRD reference - Troubleshooting — Common issues and how to fix them
- Reconciler Overview — How the operator pipeline works
- Validation Reconciler — Namespace opt-in and service checks
- Routing Reconciler — Gateway API and
HTTPRoutemanagement - Authentication Reconciler — OIDC, Keycloak, and
SecurityPolicy
- Makefile Reference — All build, test, and deployment targets
- Release Process — How releases are created
- Release Checklist — Step-by-step release guide for maintainers
- Release Setup — GitHub Actions configuration
Contributions are welcome! To get started:
git clone https://github.com/nebari-dev/nebari-operator.git
cd nebari-operator
# Make your changes, then:
make fmt vet test lint- Fork the repo and create a feature branch (
git checkout -b feat/my-feature) - Add tests for new functionality
- Ensure
make fmt vet test lintpasses - Open a Pull Request — CI will build multi-arch images and post image details
Documentation:
- Contributing Guide — Development workflow and conventions
- API Reference — Auto-generated CRD field reference
See our issue tracker for open issues and ideas.
Apache License 2.0 — see LICENSE for details.