{"record":{"id":"3d1a2113372f3b34","repo":"grpc/grpc-go","slug":"failed-to-parse-auditcondition-v-allowed-values","errorCode":null,"errorMessage":"failed to parse AuditCondition %v. Allowed values {NONE, ON_DENY, ON_ALLOW, ON_DENY_AND_ALLOW}","messagePattern":"failed to parse AuditCondition (.+?)\\. Allowed values (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"authz/rbac_translator.go","lineNumber":299,"sourceCode":"\t\tpolicies[policyName] = &v3rbacpb.Policy{\n\t\t\tPrincipals:  []*v3rbacpb.Principal{parsePeer(rule.Source)},\n\t\t\tPermissions: []*v3rbacpb.Permission{permission},\n\t\t}\n\t}\n\treturn policies, nil\n}\n\n// Parse auditLoggingOptions to the associated RBAC protos. The single\n// auditLoggingOptions results in two different parsed protos, one for the allow\n// policy and one for the deny policy\nfunc (options *auditLoggingOptions) toProtos() (allow *v3rbacpb.RBAC_AuditLoggingOptions, deny *v3rbacpb.RBAC_AuditLoggingOptions, err error) {\n\tallow = &v3rbacpb.RBAC_AuditLoggingOptions{}\n\tdeny = &v3rbacpb.RBAC_AuditLoggingOptions{}\n\n\tif options.AuditCondition != \"\" {\n\t\trbacCondition, ok := v3rbacpb.RBAC_AuditLoggingOptions_AuditCondition_value[options.AuditCondition]\n\t\tif !ok {\n\t\t\treturn nil, nil, fmt.Errorf(\"failed to parse AuditCondition %v. Allowed values {NONE, ON_DENY, ON_ALLOW, ON_DENY_AND_ALLOW}\", options.AuditCondition)\n\t\t}\n\t\tallow.AuditCondition = v3rbacpb.RBAC_AuditLoggingOptions_AuditCondition(rbacCondition)\n\t\tdeny.AuditCondition = toDenyCondition(v3rbacpb.RBAC_AuditLoggingOptions_AuditCondition(rbacCondition))\n\t}\n\n\tfor i, config := range options.AuditLoggers {\n\t\tif config.Name == \"\" {\n\t\t\treturn nil, nil, fmt.Errorf(\"missing required field: name in audit_logging_options.audit_loggers[%v]\", i)\n\t\t}\n\t\tif config.Config == nil {\n\t\t\tconfig.Config = &structpb.Struct{}\n\t\t}\n\t\ttypedStruct := &v1xdsudpatypepb.TypedStruct{\n\t\t\tTypeUrl: typeURLPrefix + config.Name,\n\t\t\tValue:   config.Config,\n\t\t}\n\t\tcustomConfig, err := anypb.New(typedStruct)\n\t\tif err != nil {","sourceCodeStart":281,"sourceCodeEnd":317,"githubUrl":"https://github.com/grpc/grpc-go/blob/03255a9237b6eb32710f6bc4f2de9a675b99fe36/authz/rbac_translator.go#L281-L317","documentation":"Raised by auditLoggingOptions.toProtos when the policy's audit_logging_options.audit_condition string is not a key in the RBAC_AuditLoggingOptions_AuditCondition enum map. The gRPC authz SDK accepts exactly NONE, ON_DENY, ON_ALLOW, ON_DENY_AND_ALLOW (case-sensitive, as defined in the envoy.config.rbac.v3 RBAC proto). Any other value — including lowercase variants or typos — is rejected.","triggerScenarios":"The authorization-policy JSON contains an audit_logging_options block whose \"audit_condition\" is misspelled, lowercase, or from an older/newer schema. toProtos looks up the string in the enum-value map and the `!ok` branch fires.","commonSituations":"Using lowercase \"on_deny\" instead of \"ON_DENY\"; copying an Envoy-style enum value not in the SDK's allow-list; upgrading the authz SDK and an old audit_condition value was removed; a typo like \"ON_DENY_AND_ALL\".","solutions":["Set audit_condition to one of the four exact strings: NONE, ON_DENY, ON_ALLOW, ON_DENY_AND_ALLOW (uppercase).","Remove the audit_logging_options block entirely if you don't need auditing — it defaults cleanly.","Pin your policy template to the enum values documented for your exact grpc-go authz version.","Add a CI lint that checks audit_condition against the allowed set before deploy."],"exampleFix":"// before:\n\"audit_logging_options\": { \"audit_condition\": \"on_deny\" }   // lowercase -> rejected\n\n// after:\n\"audit_logging_options\": { \"audit_condition\": \"ON_DENY\" }","handlingStrategy":"validation","validationCode":"var allowedAuditConditions = map[string]bool{\n    \"NONE\": true, \"ON_DENY\": true, \"ON_ALLOW\": true, \"ON_DENY_AND_ALLOW\": true,\n}\nfunc validateAuditCondition(policyStr string) error {\n    var p struct {\n        AuditLoggingOptions struct {\n            AuditCondition string `json:\"audit_condition\"`\n        } `json:\"audit_logging_options\"`\n    }\n    if err := json.Unmarshal([]byte(policyStr), &p); err != nil { return err }\n    c := p.AuditLoggingOptions.AuditCondition\n    if c != \"\" && !allowedAuditConditions[c] {\n        return fmt.Errorf(\"invalid audit_condition %q; allowed: NONE, ON_DENY, ON_ALLOW, ON_DENY_AND_ALLOW\", c)\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always use the exact uppercase enum strings.","Omit audit_logging_options if auditing is not needed.","Pin policy templates to your authz SDK version's enum set.","CI-lint audit_condition against the allow-list."],"tags":["authz","rbac","audit-logging","config","enum"],"analyzedSha":"03255a9237b6eb32710f6bc4f2de9a675b99fe36","analyzedAt":"2026-08-07T00:29:34.215Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}