Introduction
Wardn — GitOps continuous delivery for Kubernetes. Enterprise features, not enterprise complexity.
Wardn
Wardn is a GitOps-first continuous delivery platform for Kubernetes. It reconciles App custom resources — resolving sources (Git repo or container image), applying manifests with server-side apply, checking health, and reporting status back to the platform.
Enterprise features, not enterprise complexity. Three components. Built-in auth. A UI that doesn't require a YAML editor to create an application.
How It Works
┌────────────┐ ┌────────────┐ ┌─────────────────┐
│ Git Repo │────▶│ Operator │────▶│ K8s Cluster │
│ or Image │ │ (reconcile)│ │ (target state) │
│ │ └─────┬──────┘ └─────────────────┘
└────────────┘ │
├──▶ Resolve source (Git / Image)
├──▶ Render manifests (Raw / Kustomize)
├──▶ Server-side apply with pruning
├──▶ Health checks per resource
├──▶ Notifications (Slack)
└──▶ Status → App CR → Server → UITwo source types work today:
Git— clone a repo, render manifests from a path (raw YAML/JSON or a Kustomize overlay), apply themImage— point at a container image; the operator renders a Deployment + Service (+ optional Ingress/HPA) — no YAML needed
HelmChart and Catalog source types are reserved in the CRD — 📋 planned, no resolver wired yet.
The model — orgs → clusters → deployments → apps
org
└──▶ registered clusters
└──▶ deployments — a (cluster, namespace) pair
└──▶ Apps whose destination points thereA deployment isn't a separate resource — it's the cluster/namespace boundary an App's spec.destination targets. Several apps can share one deployment; RBAC scope deployment with scope_id like prod-cluster/default covers all of them. POST /apps validates the namespace against the cluster's registered allowlist, so a deployment is implicitly gated by which namespaces a cluster permits.
Why Wardn?
| Feature | Wardn | ArgoCD | Flux |
|---|---|---|---|
| Components | 3 (server, operator, frontend) | 5+ (server, repo-server, controller, dex, redis) | 1 (operator only) |
| Built-in UI | Yes — dashboard with app wizard | Yes | No |
| Auth | Built-in (Better Auth: local + GitHub OAuth) | Separate Dex component | None |
| Image deploys | Yes — no-YAML image source | No | No |
| RBAC | Org roles + cluster/deployment scopes | CAS config in YAML | None |
| MCP server | Yes — scoped API keys for agents | No | No |
Key Features
Core GitOps — available
- Git synchronization — clone/pull with revision tracking
- Manifest rendering — raw YAML/JSON and Kustomize overlays (Helm planned)
- Server-side apply — field manager
wardn-operator, forced ownership, automatic pruning - Health checks — per-kind logic for Deployment, StatefulSet, DaemonSet, Job, Pod
- Sync policies — automated sync, prune, freeze, and an approval gate
- Rollback — pinned-revision rollback from sync history
- Multi-cluster — register target clusters; the operator fetches kubeconfigs on demand
Platform & Security — available
- Authentication — Better Auth (local users + GitHub OAuth) in the platform app
- API keys — scoped, expirable keys for CI and MCP agents
- RBAC — org roles (Owner/Admin/Contributor/Viewer) plus scoped bindings (read/sync/admin) per cluster or deployment
- Audit logging — org-scoped activity trail
- Cluster shell — WebSocket terminals and per-cluster shell pods
- MCP server — JSON-RPC endpoint with per-tool RBAC and human-in-the-loop remediations
Secret Management
- Secret stores ✅ — Vault/OpenBao, SOPS age keys, and ESO references managed via API/UI
- External Secrets ✅ —
env.storeon image sources rendersExternalSecretobjects - Vault direct fetch ✅ — image-source env vars resolved from Vault/OpenBao at apply time
- SOPS decrypt-at-apply 📋 — the age store exists; file decryption isn't wired yet
Notifications & Webhooks
- Slack ✅ — sync success/failure notifications per app
- Incident webhooks ✅ — HMAC-signed outbound deliveries with retry
- GitHub webhook 🚧 — push events trigger syncs; HMAC signature validation is 📋 planned
- GitLab webhook 📋 — endpoint exists but parses nothing yet
Quick Start
git clone https://github.com/future-pirate-king/wardn.git
cd wardn
docker compose up -d- Platform dashboard:
http://localhost:3002 - Docs site:
http://localhost:3001 - API:
http://localhost:8080(GET /api/v1/health)
The operator needs a Kubernetes cluster — it exits in plain Docker Compose without one. For end-to-end app syncs locally, layer on docker-compose.k8s.yml (k3s + Gitea + OpenBao). See Getting Started.
Status Legend
Throughout the docs, feature status is marked consistently:
| Icon | Meaning |
|---|---|
| ✅ | Available — implemented and working |
| 🚧 | Partial — some parts work; limitations noted inline |
| 📋 | Planned — schema or design exists; not implemented |
| ❌ | Missing — documented once, but no code exists |
Documentation Sections
Getting Started
Install Wardn and deploy your first application
Configuration
App CRD spec, fields, and examples
Guides
Step-by-step tutorials for common workflows
Secret Management
Vault/OpenBao, SOPS age, and External Secrets
API Reference
REST API documentation with examples
Operator
Operator architecture, CRD reference, and reconciliation loop
Server
API server architecture, configuration, and RBAC
CLI Reference
Command-line tool and MCP proxy
MCP Server
Connect agents to Wardn over JSON-RPC
Community
- GitHub Issues — bug reports
- GitHub Discussions — technical discussions