ADR-0028 — Pull-based GitOps with ArgoCD; separate config repo
- Status: Deferred
- Date: 2026-06-11
- Related: platform/06 GitOps, platform/README, ADR-0032, ADR-0034
V1 Freeze (2026-06-12): Deferred. V1 deploys via Docker Compose (self-host) and direct Helm; no cluster fleet or pull-based CD. Re-opens at P4 (extraction & scale).
Context
BitVault needs continuous delivery to multiple Kubernetes clusters/environments that is
auditable, drift-resistant, rollback-able, and secure. The central security question is
where do cluster credentials live: a push model (CI runs kubectl/helm upgrade)
puts production credentials in CI, the most-attacked surface in the org.
Decision
Adopt pull-based GitOps with ArgoCD:
- Git is the source of truth; ArgoCD (running in each cluster) reconciles live state toward Git, with drift detection + self-heal + prune.
- CI never holds a kubeconfig — it pushes images + opens a PR to the GitOps repo; CD is ArgoCD pulling (ADR-0032).
- Separate the GitOps/config repo from the app repo, and keep ArgoCD resources separate from application manifests (industry guidance).
- App-of-apps + ApplicationSets generate the (service × env × cluster) matrix; AppProjects constrain repos/clusters/namespaces; sync waves order resources.
- ArgoCD per cluster (prod + nonprod each own one), bootstrapped by OpenTofu (ADR-0031) — no single ArgoCD holds prod+nonprod creds.
Consequences
Positive
- Every change is reviewed, attributable, and revertable (
git revert= rollback). - Drift can’t silently accumulate; the cluster always matches Git.
- Declarative cluster rebuild (re-sync from Git) — the DR superpower (ADR-0033).
- Minimal CI attack surface (no cluster creds).
Negative / costs
- A GitOps repo + a reconciler to operate; “deploy” = merge PR + wait for reconcile (slightly higher latency than direct apply).
- Secrets need a GitOps-compatible flow (no plaintext in Git, ADR-0030).
Alternatives considered
- Push CD (CI deploys): simple but CI holds cluster creds, no drift control, ad-hoc rollback. Rejected.
- Flux: equivalent GitOps; ArgoCD chosen for UI, ApplicationSets, AppProjects, and Argo Rollouts synergy (ADR-0029).
- Hub ArgoCD for all clusters: single pane but cross-env credential blast radius. Rejected for prod isolation.
Scaling
ApplicationSet generators render large matrices from few manifests; Git webhooks give instant sync; controllers shard if needed; mono-GitOps-repo splits per-team via AppProjects only if contention appears.