{"record":{"id":"52647cae9003aa95","repo":"argoproj/argo-workflows","slug":"failed-to-list-sso-rbac-service-accounts-w","errorCode":null,"errorMessage":"failed to list SSO RBAC service accounts: %w","messagePattern":"failed to list SSO RBAC service accounts: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/auth/gatekeeper.go","lineNumber":235,"sourceCode":"\tif req == nil {\n\t\treturn \"\"\n\t}\n\tnamespacedRequest, ok := req.(servertypes.NamespacedRequest)\n\tif !ok {\n\t\treturn \"\"\n\t}\n\treturn namespacedRequest.GetNamespace()\n}\n\nfunc precedence(serviceAccount *corev1.ServiceAccount) int {\n\ti, _ := strconv.Atoi(serviceAccount.Annotations[common.AnnotationKeyRBACRulePrecedence])\n\treturn i\n}\n\nfunc (s *gatekeeper) getServiceAccount(claims *authTypes.Claims, namespace string) (*corev1.ServiceAccount, error) {\n\tlist, err := s.cache.ServiceAccountLister.ServiceAccounts(namespace).List(labels.Everything())\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to list SSO RBAC service accounts: %w\", err)\n\t}\n\tvar serviceAccounts []*corev1.ServiceAccount\n\tfor _, serviceAccount := range list {\n\t\t_, ok := serviceAccount.Annotations[common.AnnotationKeyRBACRule]\n\t\tif !ok {\n\t\t\tcontinue\n\t\t}\n\t\tserviceAccounts = append(serviceAccounts, serviceAccount)\n\t}\n\tsort.Slice(serviceAccounts, func(i, j int) bool { return precedence(serviceAccounts[i]) > precedence(serviceAccounts[j]) })\n\tfor _, serviceAccount := range serviceAccounts {\n\t\trule := serviceAccount.Annotations[common.AnnotationKeyRBACRule]\n\t\tv, err := jsonutil.Jsonify(claims)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to marshall claims: %w\", err)\n\t\t}\n\t\tallow, err := argoexpr.EvalBool(rule, v)\n\t\tif err != nil {","sourceCodeStart":217,"sourceCodeEnd":253,"githubUrl":"https://github.com/argoproj/argo-workflows/blob/35bff19146f5a6ada77468c431f2624bd577e373/server/auth/gatekeeper.go#L217-L253","documentation":"When SSO is enabled, the gatekeeper maps OIDC claims to a ServiceAccount by listing ServiceAccounts in the namespace through the informer cache and matching RBAC-rule annotations. If the cache lister fails, rbacAuthorization cannot proceed and returns 'failed to list SSO RBAC service accounts: <err>'. This is almost always a cache/informer or API connectivity problem, not a user permission issue.","triggerScenarios":"An SSO-authenticated request reaches rbacAuthorization while the informer cache is not yet synced, the informer watch to the Kubernetes API broke, the argo-server lacks RBAC permission to list service accounts in the target namespace (e.g. namespaced mode with a missing role), or the k8s API is unreachable/timeout.","commonSituations":"Requests right after argo-server startup before the ResourceCache syncs; network flaps or API server restarts; installing argo-server with an RBAC role missing `serviceaccounts: list` (custom minimal installs); heavy API load causing lister errors.","solutions":["Retry the request — if the cache was still warming after startup, it will succeed once informers sync.","Check argo-server logs for informer/cache errors; restart the argo-server pod if the watch is broken.","Verify argo-server RBAC: the cluster role must allow `list` on `serviceaccounts` (and in namespaced mode, in the target namespace).","Confirm k8s API reachability from the argo-server pod (`kubectl exec` + curl the API server) and check for network policies blocking it.","If the error persists on every SSO request, check that the ServiceAccounts with `workflows.argoproj.io/rbac-rule` annotations exist in the SSO namespace."],"exampleFix":"// before: minimal install role missing serviceaccount list\nrules:\n- apiGroups: [\"argoproj.io\"]\n  resources: [\"workflows\"]\n  verbs: [\"get\", \"list\"]\n// after: allow SSO RBAC-rule mapping\nrules:\n- apiGroups: [\"\"]\n  resources: [\"serviceaccounts\"]\n  verbs: [\"get\", \"list\", \"watch\"]\n- apiGroups: [\"argoproj.io\"]\n  resources: [\"workflows\"]\n  verbs: [\"get\", \"list\"]","handlingStrategy":"retry","validationCode":"// before issuing the request, confirm cache readiness and RBAC\nsaList, err := kubeClient.CoreV1().ServiceAccounts(ssoNamespace).List(ctx, metav1.ListOptions{})\nif err != nil {\n    return fmt.Errorf(\"argo-server cannot list service accounts (check RBAC role): %w\", err)\n}","typeGuard":"func isCacheListErr(err error) bool {\n    return err != nil && strings.Contains(err.Error(), \"failed to list SSO RBAC service accounts\")\n}","tryCatchPattern":"resp, err := client.GetWorkflow(ctx, req)\nif err != nil && isCacheListErr(err) {\n    time.Sleep(2 * time.Second) // allow informer cache to re-sync\n    resp, err = client.GetWorkflow(ctx, req)\n}","preventionTips":["Grant argo-server's service account list/watch on serviceaccounts in the SSO namespace.","Add readiness probes that wait for informer cache sync before routing traffic to argo-server.","Annotate the service accounts with workflows.argoproj.io/rbac-rule so mapping has candidates.","Monitor argo-server logs for informer watch breaks and alert/restart on persistent cache errors."],"tags":["kubernetes","argo-workflows","sso","rbac","informer-cache"],"backgroundTag":"informer-cache-sync-failed","analyzedSha":"35bff19146f5a6ada77468c431f2624bd577e373","analyzedAt":"2026-09-03T19:34:35.908Z","contentChangedAt":"2026-09-03T19:34:35.908Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}