Production-Grade GitOps on AWS: Verified Release Promotion Across EKS Environments with Argo CD and Kargo A developer detailed a production-grade GitOps architecture on AWS that uses separate EKS clusters per environment, ECR as the registry, OIDC federation instead of static credentials, and Kargo to automate release promotion between environments. The setup includes automated verification gates backed by real metrics before promotion, and emphasizes promoting image digests rather than tags to ensure byte-identical artifacts reach production. There's a moment every platform team hits: Argo CD is syncing beautifully, deployments are declarative, and yet moving a release from dev to staging to production still means a human editing a values file and hoping. The deployment problem is solved; the promotion problem isn't. In this article, I want to walk through how we close that gap on AWS: separate EKS clusters per environment, ECR as the registry, OIDC federation everywhere instead of static credentials, ApplicationSets instead of copy-pasted manifests, and — critically — automated verification gates backed by real metrics before anything gets promoted. This is the architecture my team runs variations of in production, and the reasoning behind each decision. Before touching any tool, it's worth being precise about what "promotion" means in a GitOps world. Argo CD's job is narrow and it does it extremely well: make the cluster match what Git says. It does not decide when a new version should move from dev to staging to production. That decision — historically made by a human editing a values file, or by a brittle CI job running sed against your repo — is the promotion problem. Kargo exists to own exactly that gap. It watches your artifact sources ECR, Git, Helm repos , models each environment as a Stage , packages new artifact versions as Freight , and promotes that Freight between stages by writing commits to your GitOps repo. Argo CD then does what it always does: reconcile. The result is a clean separation of concerns: Every environment's state is a commit. Every promotion is auditable. Rollback is git revert . That's the whole philosophy. The single biggest gap between tutorial GitOps and production GitOps is environment isolation. Namespaces on a shared cluster do not give you blast-radius isolation. A misbehaving controller, a noisy neighbor exhausting node resources, a cluster upgrade gone wrong — all of these take dev and prod down together. In a real AWS setup: That last point deserves emphasis: the artifact that reaches production must be byte-identical to the one validated in staging . Rebuilding "the same" image per environment silently invalidates everything your pipeline verified. Promote digests, not tags. If your GitHub Actions workflow authenticates to AWS with an AWS ACCESS KEY ID stored in repository secrets, that's a standing credential waiting to leak. GitHub's OIDC provider lets each workflow run exchange a short-lived, cryptographically verifiable token for a scoped IAM role session: permissions: id-token: write contents: read steps: - uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: arn:aws:iam::