TL;DR: Synacktiv found a way to run code on Argo CD's repo-server with no auth, and it walks straight to full cluster takeover. Argo CD is one of the most common GitOps controllers, so this touches a lot of clusters. It takes a foothold in the cluster first, and that bar is low: one compromised pod. There's no CVE, no patch, and it's been open 18 months. The fix is a NetworkPolicy the Helm chart shipped switched off until version 10.0.0, so plenty of clusters are still wide open.
In a normal cluster-wide setup, Argo CD is the one thing allowed to touch every namespace. It reads your Git repos and applies whatever it renders. Synacktiv showed its repo-server will take those rendering instructions from anyone who can reach it inside the cluster, no login, and turn them into code execution. Here's the path, and how to shut it.
Attack of the Week: the repo-server trusts anyone who can reach it
Hugo Vincent at Synacktiv, "Caught in the Octopus Trap: Unauthenticated RCE in Argo CD with CodeQL" [2026-07-01].
How it runs. First, the catch: you have to be able to reach the repo-server from inside the cluster. Synacktiv's bar for that is one compromised pod. So think of it as a post-foothold move: once someone's inside on a single pod, this is how they turn that into the whole cluster.
Argo CD has two halves, an API server and a repo-server. The repo-server is the one that turns your Git repos into Kubernetes manifests, and it listens on a gRPC port with no auth. Anything that can reach that port can call it.
The call that matters is GenerateManifest. It takes a KustomizeOptions.BuildOptions field, and that field lands unsanitized in exec.Command(). The same request also names the Git repo the files come from, so you point it at one you control. Kustomize's --helm-command flag lets you swap in the binary it runs, so point that at a script in your repo and the repo-server runs it. No creds, no prompt.
Now you've got code execution on the repo-server. From there you read REDIS_PASSWORD out of the environment and connect to Argo CD's Redis cache, which Argo CD trusts completely. Poison the cached manifest for a real app, and on the next sync Argo CD pushes your manifest to the cluster with its own permissions. Auto Sync makes that automatic; without it, it lands the next time someone syncs by hand. The thing allowed to deploy anything now deploys what you wrote. That's the whole cluster.
Synacktiv found it with CodeQL and reported it in January 2025. Eighteen months on, it's still open and still has no CVE. Their words: "the vulnerability remains unpatched." They built an exploit tool, argo-cdown, and are sitting on the release.
The fix is one Helm value: a NetworkPolicy that keeps stray pods off the repo-server and Redis. Argo CD's chart ships that policy built in, and for years shipped it turned off. The master switch global.networkPolicy.create defaulted to false, so a stock install left the repo-server open across the cluster.
Chart 10.0.0 (advisory GHSA-47m3-95c7-g2g8) flipped that default on. That shuts the repo-server and Redis path, with two gaps left over: global.networkPolicy.defaultDenyIngress stays false, and the metrics port is reachable cluster-wide. Older charts, and installs still carrying old values, are open. Set global.networkPolicy.create: true yourself.
And it compounds. The same week, Paul Barbé at Synacktiv wrote up Helm template injection [2026-06-29]. If a chart drops your .Values into its YAML without quoting, one multi-line value (using | or |-) can inject whole Kubernetes objects into the rendered manifest. Argo CD renders those charts. So the controller you just locked down can still turn one sloppy chart value into pods or namespaces the chart never meant to create.

The Argo CD repo-server chain, stage by stage, from one open internal port to full cluster control.
Ship This Week.
Set
global.networkPolicy.create: truein your Argo CD values, or jump to argo-helm chart10.0.0or later, which turns it on for you. This is the one that closes the RCE path.Check that the policy really does keep stray pods off the repo-server's gRPC port and Redis, since that's the path this uses. And flip
global.networkPolicy.defaultDenyIngresson as a backstop; it's stillfalseeven in10.0.0.Treat the repo-server as tier-zero. It runs code and holds the Redis password, so whatever reaches it can reach your cluster.
There's no patch coming and no CVE to track, so the network boundary is the fix.

Four controls, each mapped to the attack stage it caps: the NetworkPolicy closes the RCE path, the other three add defense in depth.
Defender's Corner: check what your cluster logging catches
Before you trust your detections, read AWS's own catalog. AWS's IR team (Shannon Brazil, Cydney Stude, Javier Teitelbaum) just added five in-the-wild techniques to its Threat Technique Catalog [2026-06-29]. Three are EKS-specific, and they line up with the kind of takeover this issue is about. One is the way in: an exposed API server or ingress that lands them in a pod (T1190). That's the foothold the Argo CD bug needs. The other two are what they do once inside: swapping images or slipping sidecars into running workloads (AT1668), and mining on your compute when nothing caps it (T1496.A010).
Notice where AWS points you for each. For T1190 it's the same lesson as the Argo CD fix: cut public API-server exposure, use network policies, keep service accounts least-privilege. For AT1668 and T1496.A010 it adds image signing and admission control, RBAC, resource quotas, and GuardDuty EKS Protection. AWS only gives you concrete CloudTrail event names for the two account-level moves: a compromised management account running sts:AssumeRoot into member accounts (AT1669), and inviting a stray account into an org you control to push SCPs onto it (T1666.A003, events organizations:InviteAccountToOrganization and organizations:AcceptHandshake). Each comes with an SCP.
The gap is in the logging. All five leave traces in both CloudTrail and Kubernetes audit logs, but AWS only gives you ready-made CloudTrail events for the account-level ones. So if your detections live entirely in CloudTrail, you've got the org-level moves covered and you're thin on the EKS ones until you're also watching Kubernetes audit logs and GuardDuty.
Do this week: turn on GuardDuty EKS Protection and make sure Kubernetes audit logging is on for every production cluster, so the in-cluster stuff is visible at all. Then drop in the SCP that limits who can call sts:AssumeRoot, and alert on the two organizations events.
Agent Bench: point an agent at your Argo CD and Helm config
Both start in files you already have. The takeover path and the Helm injection both start in your Git repos and your Argo CD values, and a coding agent will read all of it faster than you will. Point one at those two places and ask it three things:
Is
global.networkPolicy.createset, and which pods can reach the repo-server and Redis today? If nothing's stopping them, the repo-server is reachable and this whole path is live.Which chart values land in templates unquoted? Any untrusted
.Valuesthat goes into YAML with no quoting, type coercion, or schema is a candidate for Barbé's injection. Have it list each one.Any
AppProjectwith noclusterResourceWhitelist, which is what stops an injected manifest from spinning up cluster-scoped objects.
Have it give you a file:line for each finding, plus the files that decide reachability, so you can check the path yourself. Agents love to over-report what's reachable, and something it calls exposed might sit behind a policy three files over. You verify by hand; that's the gate.
What you walk away with: which charts splice unquoted input into manifests, and whether your repo-server is walled off, both at file:line.
Try it this week: point an agent at the one repo that feeds your production Argo CD. Start with global.networkPolicy.create and every unquoted .Values in your biggest chart.
📡 Also on the Radar
Alex Plaskett at NCC Group, "An Introduction to AI Coding Agent Security" [2026-06-18] walks Claude Code, Cursor, and Codex and shows where the guardrails hold and where they slip. It ties straight back to this issue. The agent writing your manifests is one more untrusted input into the same pipeline: an indirect prompt injection in a file it reads, an auto-mode that says yes to everything, a tool call with no sandbox, and suddenly it's the one committing the bad chart. Plaskett's fixes are the boring ones that work. Set permission modes to ask, scope tool access down, and give it real process isolation (he reaches for Bubblewrap) instead of trusting it by default. Give these agents commit and deploy rights and they take on the same tier-zero risk as everything else in the pipeline.
Your deploy pipeline is tier-zero now, all the way from the GitOps controller down to the agent writing the chart. Anywhere that NetworkPolicy is still off, which was the chart default before 10.0.0 and is still the case on plenty of clusters, the Argo CD repo-server is reachable from the rest of the cluster, and code execution there lets someone poison Redis and have Argo CD push a malicious manifest with full cluster rights. So: what's the one thing in your pipeline that can touch every namespace, and when did you last check who can reach it?
Know someone who runs Argo CD? Forward this to them.
How was this issue?
Your employees are connecting AI to everything. Now what?
ChatGPT and Claude don't just answer questions anymore. Employees are connecting them directly to Notion, Linear, Jira, and the rest of your stack. The AI can read, write, and take actions on company data. Most IT and security teams have no visibility into any of it.
Harmonic Security Connectors changes that. It sits inline with every AI-to-app connection, so you see each call, control what data moves, and block destructive actions before they happen. Employees notice nothing different.
See what's actually running across your business in a live demo.

