{"record":{"id":"d3d3682d66b1b985","repo":"grpc/grpc-go","slug":"rbac-policy-checkedcondition-is-present","errorCode":null,"errorMessage":"rbac: policy.CheckedCondition is present","messagePattern":"rbac: policy\\.CheckedCondition is present","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/xds/httpfilter/rbac/rbac.go","lineNumber":68,"sourceCode":"\nfunc (builder) TypeURLs() []string {\n\treturn []string{\n\t\t\"type.googleapis.com/envoy.extensions.filters.http.rbac.v3.RBAC\",\n\t\t\"type.googleapis.com/envoy.extensions.filters.http.rbac.v3.RBACPerRoute\",\n\t}\n}\n\n// Parsing is the same for the base config and the override config.\nfunc parseConfig(rbacCfg *rpb.RBAC) (httpfilter.FilterConfig, error) {\n\t// All the validation logic described in A41.\n\tfor _, policy := range rbacCfg.GetRules().GetPolicies() {\n\t\t// \"Policy.condition and Policy.checked_condition must cause a\n\t\t// validation failure if present.\" - A41\n\t\tif policy.Condition != nil {\n\t\t\treturn nil, errors.New(\"rbac: Policy.condition is present\")\n\t\t}\n\t\tif policy.CheckedCondition != nil {\n\t\t\treturn nil, errors.New(\"rbac: policy.CheckedCondition is present\")\n\t\t}\n\n\t\t// \"It is also a validation failure if Permission or Principal has a\n\t\t// header matcher for a grpc- prefixed header name or :scheme.\" - A41.\n\t\t//\n\t\t// \"Envoy aliases :authority and Host in its header map implementation,\n\t\t// so they should be treated equivalent for the RBAC matchers; there must\n\t\t// be no behavior change depending on which of the two header names is\n\t\t// used in the RBAC policy.\" - A41. Any header matcher with value \"host\"\n\t\t// is rewritten to \":authority\", as that is what grpc-go shifts both\n\t\t// headers to in the transport layer.\n\t\t//\n\t\t// Both rules apply to header matchers nested inside and/or/not rules, so\n\t\t// the whole permission and principal trees are walked.\n\t\tfor _, principal := range policy.GetPrincipals() {\n\t\t\tif err := normalizePrincipalHeaders(principal); err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}","sourceCodeStart":50,"sourceCodeEnd":86,"githubUrl":"https://github.com/grpc/grpc-go/blob/0c51461d27177d997e14c642fe18c11668fc09a3/internal/xds/httpfilter/rbac/rbac.go#L50-L86","documentation":"Symmetric to error 72: gRFC A41 also requires that the `checked_condition` field of an RBAC Policy cause a validation failure if present. parseConfig (rbac.go:67-68) returns this error for any policy whose `CheckedCondition` is non-nil. gRPC's RBAC engine does not implement checked conditions (a conditional-CEL feature in Envoy), so it refuses the config outright.","triggerScenarios":"Triggered when an xDS-delivered RBAC config sets `checked_condition` on any policy within Rules.Policies. Caught during resource parsing, causing the resource to be NACK'd.","commonSituations":"Reusing an Envoy-targeted RBAC policy that uses checked_condition with a gRPC xDS client; an Istio authorization policy that compiles to checked_condition being delivered to gRPC; a control-plane upgrade that started emitting checked_condition.","solutions":["Remove the `checked_condition` field from RBAC policies delivered to gRPC clients.","Re-express the authorization logic using the supported permission/principal matcher primitives (header, path, source IP, JWT claim, etc.).","Use RBACPerRoute or separate filter chains to keep the Envoy-only policy away from gRPC."],"exampleFix":"// before\npolicies:\n  p1:\n    checkedCondition:\n      condition: \"connection.requested_server_name == 'a'\"\n    permissions: [...]\n\n// after\npolicies:\n  p1:\n    permissions: [{ any: true }]\n    principals:\n      - authenticated: { principalName: { exact: \"spiffe://acme/a\" } }","handlingStrategy":"validation","validationCode":"func validateRBACPolicyForGRPC(rbac *rpb.RBAC) error {\n    for name, p := range rbac.GetRules().GetPolicies() {\n        if p.GetCheckedCondition() != nil {\n            return fmt.Errorf(\"policy %q: gRPC does not support Policy.checked_condition\", name)\n        }\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never emit `checked_condition` in RBAC policies destined for gRPC clients.","Re-express the logic as supported permission/principal matchers.","Maintain a shared policy linter that flags A41-unsupported fields for both `condition` and `checked_condition`."],"tags":["grpc","xds","rbac","security","validation","a41"],"backgroundTag":null,"analyzedSha":"0c51461d27177d997e14c642fe18c11668fc09a3","analyzedAt":"2026-08-11T14:49:15.055Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}