| Package | Affected versions | Patched versions |
|---|---|---|
| github.com/argoproj/argo-workflows | all versions | |
| github.com/argoproj/argo-workflows/v2 | all versions | |
| github.com/argoproj/argo-workflows/v3 | all versions | |
| github.com/argoproj/argo-workflows/v4 | ≥ 4.0.0, < 4.0.5 | 4.0.5 |
| argo workflows | ≥ 4.0.0, < 4.0.5 | 4.0.5 |
A nil pointer dereference in server/auth/gatekeeper.go rbacAuthorization() causes a panic (denial of service) for SSO users whose claims match a namespace-level RBAC rule but not an SSO-namespace rule, when SSO_DELEGATE_RBAC_TO_NAMESPACE=true.
When getServiceAccount(claims, ssoNamespace) returns nil (no matching rule), the error is suppressed and loginAccount remains nil. If RBAC delegation finds a matching namespaceAccount, line 304 calls precedence(loginAccount) which unconditionally accesses serviceAccount.Annotations — nil pointer dereference.
Affected code (v4.0.4):
// gatekeeper.go:304
} else if precedence(namespaceAccount) > precedence(loginAccount) {
// loginAccount is nil here -> precedence(nil) -> PANIC
// gatekeeper.go:232-234
func precedence(serviceAccount *corev1.ServiceAccount) int {
i, _ := strconv.Atoi(serviceAccount.Annotations[common.AnnotationKeyRBACRulePrecedence])
return i
}
Live-tested 2026-04-17: kind cluster, Argo Workflows v4.0.4, Dex v2.43.1 OIDC provider.
--auth-mode=sso --auth-mode=client, SSO pointing to Dex, RBAC enabled.SSO_DELEGATE_RBAC_TO_NAMESPACE=true on the argo-server deployment.workflows.argoproj.io/rbac-rule: "true" annotation in a target namespace (e.g., target-ns).argo).GET /api/v1/workflows/target-ns with the SSO session cookie.{"code":13,"message":"runtime error: invalid memory address or nil pointer dereference"}Recovered from panic with stack trace at gatekeeper.go:233 (precedence()) called from gatekeeper.go:304.Every subsequent API request from affected SSO users triggers the same panic.
Permanent denial of service for any SSO user whose claims don't match SSO-namespace RBAC but do match a target namespace rule. Realistic in multi-tenant deployments with per-namespace RBAC. The gRPC recovery interceptor catches the panic so the server process survives, but the affected user gets HTTP 500 on every request.
Running one of these products? Scan your site to see whether it exposes a vulnerable version.
Scan my site freeAdd nil check: if loginAccount == nil || precedence(namespaceAccount) > precedence(loginAccount)
This advisory was prepared with AI assistance (Claude Code, Anthropic).