Attach Debug Containers via ArgoCD UI¶
This Proposal describes a feature to allow attaching debug containers to workloads via ArgoCD UI, to allow easier debugging of workloads with distroless images or workloads whose images don't contain debugging tools
Summary¶
ArgoCD currently lacks a built-in way to attach debugging tools to running workloads. Users operating pods with distroless images, or images that don't bundle debugging utilities, must rely on external tooling (e.g., raw kubectl commands, ssh into the k8s node) to troubleshoot live issues — a workflow that is cumbersome and not accessible through the ArgoCD UI. This proposal adds a Debug Containers tab to the ArgoCD pod view that lets users attach Kubernetes ephemeral containers to existing pods directly from the UI. Users can select a debug image and optionally share the target container's process — enabling tools like busybox, netshoot, or dlv to inspect a running workload. This closes the gap between ArgoCD's deployment visibility and the day-2 debugging experience, removing the need to drop out to kubectl debug for routine troubleshooting.
Motivation¶
Allowing users to attach debug containers to pods is highly useful for debugging basic network/io problems in situations where a shell those tools are not available, or in some cases, where the workload cannot be exec'ed into.
Goals¶
- Debug distroless pods, or pods missing debug tools, from ArgoCD UI.
- Network debugging from the UI (e.g. attach
netshootto check connectivity, DNS, traffic). - Attach profilers/debuggers (
dlv,py-spy) via shared PID namespace. - Debug pods where
execwon't work — distroless without a shell, crash-looping pods, pods whose entrypoint already exited.
Non-Goals¶
This proposal does not cover managing the lifecycle of already-attached ephemeral containers (Kubernetes does not support removing them)
Proposal¶
Rather than introducing a new RBAC resource, this proposal uses on the existing exec resource by adding a new action debug. The feature is gated behind a exec.debug.enabled flag in the argocd-cm ConfigMap (disabled by default). When enabled, a user with the debug action on the pod's project sees a new Debug tab on the pod view, with a dropdown of allowed debug images and a dropdown of the pod's containers for optional process-namespace sharing — enabling tools like busybox, netshoot, or dlv to inspect a running workload.
A exec.debug.images field is also exposed in argocd-cm as the cluster-wide default allowlist of images that may be used.
RBAC¶
The simple form grants the user the ability to attach any image permitted by exec.debug.images:
p, role:debugger, exec, debug, */*, allow
The action can be extended with an image pattern to further narrow which images a specific subject is allowed to attach (you cannot add images not present in exec.debug.images). Glob matching is applied against the fully-qualified image reference, and the result is intersected with the configured allowlist:
p, role:net-debug, exec, debug/docker.io/library/busybox:*, */*, allow
p, role:go-debug, exec, debug/gcr.io/example/dlv:1.22, prod/*, allow
A bare debug action (no image suffix) is equivalent to debug/* for that subject. The image dropdown shown in the UI is the intersection of the configured allowlist and the patterns the user's RBAC grants.
When a workload has a debug container attached, its Application shows a note near the Sync OK text: Sync OK (Debug Container Attached).
Use cases¶
Add a list of detailed use cases this enhancement intends to take care of.
Use case 1:¶
As a user, I would like to be able to debug workloads that are using distroless images
Implementation Details/Notes/Constraints [optional]¶
see PR
Detailed examples¶
Security Considerations¶
- This Proposal and PR use the same terminal code as the exec feature
- users who configure allow images with
latestas their tag indebug.imagescan be at risk for bad actors taking over popular images
Risks and Mitigations¶
- Bigger attack surface than
exec. Debug container ships its own binaries — shells, package managers, net tools the workload image left out.debuggrant = injecting arbitrary tooling into a live pod. Mitigation: off by default (exec.debug.enabled). Images limited to theexec.debug.imagesallowlist, RBAC supports per-image globs so a subject can be scoped tighter than the allowlist. - Mutable image tags. Allowlisting
busybox:latestmeans the image pulled at attach time can change without ArgoCD approval — compromised upstream tag lands in prod. Mitigation: No mitigation in Argo itself, but docs will show a warning againts using mutable image tags. - Resource exhaustion from a bad debug container. Ephemeral containers share the pod's cgroup, and Kubernetes does not allow
resourceson ephemeral containers — so a profiler, packet capture, or fork bomb can't be bounded the way a sidecar can, and may starve the workload or fill node ephemeral storage. Mitigation: can't fix at the container level. Treatexec.debug.imagesas a trusted-image list anddebugas a privileged grant on par withexec. Node-level protections (kubelet eviction thresholds, namespace ResourceQuotas on ephemeral storage) stay the operator's job. - PID namespace sharing exposes the target's memory and FDs. With shared PID namespace, the debug container can read
/proc/<pid>/mem,ptrace, and see the workload's file descriptors — including in-memory secrets. Mitigation: opt-in per attach; audit log captures image + target container; same RBAC asexec. - Debug history sticks around. Kubernetes won't let you remove an ephemeral container once attached — the pod spec keeps the record until the pod is replaced. Called out in Non-Goals; UI shows
Sync OK (Debug Container Attached)so the state isn't hidden.
Upgrade / Downgrade Strategy¶
- Upgrade. Gated by
exec.debug.enabledinargocd-cm, defaultfalse— upgrade is a no-op until an operator opts in. On opt-in: populateexec.debug.imagesand grantexec, debugto the relevant roles. Until then the Debug tab is hidden and the API rejects attach requests. - Downgrade. Older ArgoCD versions drop the Debug tab and the
exec, debugendpoint. Already-attached ephemeral containers keep running — they're owned by Kubernetes, not ArgoCD — and stay visible viakubectl. No ArgoCD-side cleanup needed. The new ConfigMap keys are ignored by older versions; leave them in place for a future re-upgrade or remove them, either is fine. RBAC policies referencingdebugare inert on older versions.
Drawbacks¶
Argo CD might consider limiting the attack surface that can be presented with the debug container (which is more powerful than exec'ing into a pod)
Alternatives¶
kubectl debugagainst the cluster. The status quo. Needs direct cluster creds and bypasses ArgoCD RBAC + audit — which is the reason teams that live in the ArgoCD UI want this in-product.kubectl exec(already in ArgoCD). Fine when the image has a shell and the right tools. No good for distroless, crash-looping pods, or attaching a profiler to a running PID from outside.- eBPF tooling. Good for always-on, low-overhead network and syscall introspection across the cluster. Separate platform to run, needs cluster-wide privileges, and doesn't cover interactive use (attach a debugger to a PID, run ad-hoc commands in the pod's namespaces). Complements debug containers, doesn't replace them.