On 18 September 2026 Argo Workflows released v4.1.4 and v4.0.12 and published two high-severity advisories. The first is a path traversal in how executors download directory artifacts from S3, GCS, Azure Blob and OSS: an object key containing ../ could write files outside the workspace inside the workflow pod. The second is a tenant isolation break in the workflow archive: a user allowed to list workflows in one namespace could read archived workflows, including their parameters, from every other namespace.
Neither advisory had a CVE ID when published. Both are tracked by GitHub advisory ID.
What's affected
| Advisory | CVSS 3.1 | Affected | Fixed |
|---|---|---|---|
| GHSA-vm9v-p987-xm32, artifact path traversal | 8.8 | v4.1.0 to v4.1.3, v4.0.0 to v4.0.11, all v3 releases | v4.1.4, v4.0.12 |
| GHSA-q65w-j2vp-47c4, archived workflow IDOR | 8.5 | v4.1.0 to v4.1.3 | v4.1.4 |
v3 will not be patched. The artifact advisory says plainly: "v3 is not being patched. Users on v3 should upgrade."
The artifact bug. When a workflow consumes a directory artifact, the executor lists every object under a bucket prefix and writes each one into the local workspace. The drivers computed the local path with strings.TrimPrefix and filepath.Join, and filepath.Join happily resolves ../ sequences. An object key like prefix/../../usr/local/bin/something therefore lands outside the download directory. The advisory describes the result as arbitrary file write leading to code execution inside the wait or init executor container. The attacker needs write access to the bucket or prefix the workflow reads, and in a shared bucket, any workflow author can choose their output keys.
The archive bug. Argo added == and != operators on metadata.namespace field selectors in February. The live workflow list was updated to run a cluster-wide permission check for !=. The archived workflow list was not. A request with metadata.namespace!=my-namespace passed the permission check for the caller's own namespace, while the database query returned everything else. The proof of concept in the advisory shows a tenant reading another namespace's db-password and api-key parameters. Only 4.1.0 to 4.1.3 are affected, because the selector change never reached 4.0 or 3.x.
How to check if you're exposed
Find the controller and server versions:
kubectl get deploy -A -o jsonpath='{range .items[*]}{.metadata.namespace}{"/"}{.metadata.name}{" "}{.spec.template.spec.containers[0].image}{"\n"}{end}' \
| grep -E "workflow-controller|argo-server|argocli"
Check the image tags against the table. If you deploy from a quick-start manifest that tracks :latest, pin to a release tag.
Check whether the workflow archive is on, which is what the IDOR reads from:
kubectl get cm workflow-controller-configmap -n argo -o yaml | grep -A4 "persistence:"
archive: true under persistence means it is enabled.
Find workflows and templates that pull artifacts from object storage, then review which buckets and prefixes each reads and who can write to them:
kubectl get workflowtemplates,clusterworkflowtemplates,cronworkflows -A -o yaml \
| grep -nE "^\s+(s3|gcs|azure|oss):" | head -50
To look for exploitation of the IDOR, search Argo Server access logs for archived workflow requests that use a != namespace selector. In URLs it shows up encoded as metadata.namespace!%3D.
What to do now
- Upgrade to v4.1.4 or v4.0.12. If you're on v3, plan the move to v4 now. There will be no v3 fix.
- Treat workflow parameters in the archive as possibly exposed if you ran 4.1.0 to 4.1.3 with the archive enabled and more than one tenant. Rotate any secrets that were passed as plain parameters, and move them to Kubernetes Secrets referenced by the workflow instead.
- Until you can upgrade the server, the advisory's only workaround for the IDOR is disabling the archive or restricting who can reach Argo Server.
- Separate artifact buckets by trust. Don't let workflows consume directory artifacts from buckets or prefixes that untrusted parties can write to. In shared buckets, give each team its own prefix and an IAM policy that limits writes to it.
- Check executor service accounts. The path traversal runs code inside the workflow pod, so its blast radius is whatever that pod's service account and cloud credentials can do. Keep them scoped to the one workflow.
Why it matters
Object storage keys look like file paths but aren't validated like them. Any code that turns a remote listing into local files needs the same containment checks as archive extraction. The fixed drivers now check that each key resolves inside the destination, that no ancestor escapes through a symlink, and that the final path isn't a symlink. That's a good checklist for any similar code you own.
The archive bug is a reminder that authorization fixes need to land on every path to the same data. The live list was fixed when the feature was added. The archive list, reading the same kind of object from a different store, was missed. Multi-tenant platforms should test each new query feature against every endpoint that exposes it.
Try it yourself
Pick one workflow that consumes a directory artifact. Write down the bucket, the prefix and every identity that can write to that prefix. If the list includes a CI system or team that shouldn't be able to change what the workflow runs, move the artifact to a prefix only the producing workflow can write.
Click through it at your own pace, or open it full screen.
Quick check
Is Argo Workflows 4.0.8 affected by the archived workflow IDOR?
No. The advisory says only v4.1.0 to v4.1.3 are affected, because the != namespace selector was never added to the 4.0 or 3.x lines. 4.0.8 is affected by the artifact path traversal, though, so it should go to 4.0.12.
What does an attacker need for the artifact path traversal?
Write access to the bucket or prefix a workflow reads as a directory artifact, or the ability to supply the artifact source. In a shared bucket, any workflow author who can write output keys qualifies.
Will Argo Workflows v3 get a fix?
No. The advisory states that v3 is not being patched and v3 users should upgrade.