ADR-010: Client-Local ArgoCD with Central Git Source¶
Status: Approved
Date: 2026-06-30
Decision¶
Each client control plane runs its own ArgoCD instance. The management plane installs ArgoCD and seeds the initial Application during cluster provisioning. After seeding, the client ArgoCD pulls the Inari baseline and the client's overlay directly from the central 7k-inari Git repository. The management plane does not deploy resources directly to client clusters after bootstrap.
Rationale¶
- Aligns with a pure GitOps model: every deployment is a Git commit
- Reduces management-plane attack surface — no cross-cluster kubeconfigs stored centrally
- Clients can inspect their own ArgoCD state and Application resources with read-only access
- Simpler network model: client ArgoCD pulls from Git over HTTPS/SSH; Alloy pushes observability to public management-plane endpoints
- Decouples client platform lifecycle from management-plane availability after bootstrap
Deployment Model¶
7k-inari Git Repository
├── clients/_templates/base/ # Shared baseline
├── clients/<client-id>/ # Per-client overlay
└── fleet/ # Management-plane only
▲ pull baseline + overlay
│
┌─────────────────────────────┐
│ Client ArgoCD │
│ (runs in client cluster) │
│ installed + seeded by │
│ management-plane Crossplane│
└─────────────────────────────┘
│
▼ apply
┌─────────────────────────────┐
│ Client Control Plane │
│ (Backstage, Crossplane, │
│ Dex, Alloy, Hiroba, etc.) │
└─────────────────────────────┘
Management Plane Responsibilities¶
The management plane, via Crossplane, owns:
- AWS account / org resources (manual/scripted for v1)
- VPC, subnets, routing, security groups
- EKS control plane and node groups (including upgrades)
- Cluster-level IAM and OIDC provider
- ArgoCD Helm installation
- The initial ArgoCD
Applicationpointing toclients/<client-id>/overlays/<env>/
Client ArgoCD Responsibilities¶
After seeding, the client ArgoCD owns:
- Its own configuration (via the Inari overlay)
- Its own version upgrades (when the overlay changes)
- All ArgoCD Application resources
- Deployment of Backstage, Dex, Alloy, workload Crossplane, Hiroba Catalog, OPA, etc.
Client ArgoCD Ownership¶
- Client ArgoCD is installed and seeded by 7KGroup during cluster provisioning
- Clients receive read-only access and can view ArgoCD Applications but not modify them
- Only 7KGroup can change the management-plane-owned infrastructure that hosts ArgoCD
- Only the
7k-inarirepository controls what ArgoCD deploys
Bootstrap¶
Management-plane Crossplane installs ArgoCD and creates the initial Application:
- Deploy ArgoCD via Helm into the client cluster
- Create a Git repository secret pointing to
github.com/7kgroup/7k-inari - Create an initial
Applicationpointing toclients/<client-id>/overlays/<env>/ - ArgoCD pulls and syncs the overlay, becoming self-managing
If ArgoCD is deleted, management-plane Crossplane recreates the installation and re-seeds the initial Application. The overlay then restores the rest.
Authentication to Git¶
Client ArgoCD authenticates to the 7k-inari repository using a per-client deploy key or a read-only GitHub App credential. The credential is:
- Generated during onboarding
- Scoped to the
7k-inarirepository only - Stored in the client's secret store and mounted into ArgoCD via External Secrets Operator
- Rotated on a defined schedule
Trade-offs¶
| Pros | Cons |
|---|---|
| Pure GitOps, auditable deployments | Need to secure and rotate many Git credentials (one per client) |
| No central cluster secrets | Client ArgoCD is a new component to operate per client |
| Clients can self-inspect | Initial bootstrap requires careful sequencing |
| Works over public internet | Requires Git and ArgoCD availability for deployments |
Implications for Other Decisions¶
- ADR-007 (Management Plane as Fleet Hub) is updated: the management plane owns the client cluster infrastructure and ArgoCD installation, but not ArgoCD contents.
- The
fleet/argocd/cluster-secrets/directory is not needed for client clusters. - Client overlays must be self-contained: a client ArgoCD Application should point to
clients/<client-id>/overlays/<env>/and that overlay should reference the baseline.