{"record":{"id":"851a9c47038c8fdf","repo":"grpc/grpc-java","slug":"failed-to-translate-authorization-policy","errorCode":null,"errorMessage":"Failed to translate authorization policy","messagePattern":"Failed to translate authorization policy","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"authz/src/main/java/io/grpc/authz/AuthorizationServerInterceptor.java","lineNumber":49,"sourceCode":"import java.util.List;\n\n/**\n * Authorization server interceptor for static policy. The class will get\n * <a href=\"https://github.com/grpc/proposal/blob/master/A43-grpc-authorization-api.md#user-facing-authorization-policy\">\n * gRPC Authorization policy</a> as a JSON string during initialization.\n * This policy will be translated to Envoy RBAC policies to make\n * authorization decisions. The policy cannot be changed once created. To\n * change the policy after creation, see FileWatcherAuthorizationServerInterceptor.\n */\n@ExperimentalApi(\"https://github.com/grpc/grpc-java/issues/9746\")\npublic final class AuthorizationServerInterceptor implements ServerInterceptor {\n  private final List<ServerInterceptor> interceptors = new ArrayList<>();\n\n  private AuthorizationServerInterceptor(String authorizationPolicy) \n      throws IOException {\n    List<RBAC> rbacs = AuthorizationPolicyTranslator.translate(authorizationPolicy);\n    if (rbacs == null || rbacs.isEmpty() || rbacs.size() > 2) {\n      throw new IllegalArgumentException(\"Failed to translate authorization policy\");\n    }\n    for (RBAC rbac: rbacs) {\n      interceptors.add(\n          InternalRbacFilter.createInterceptor(\n            io.envoyproxy.envoy.extensions.filters.http.rbac.v3.RBAC.newBuilder()\n            .setRules(rbac).build()));\n    }\n  }\n\n  @Override\n  public <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall(\n      ServerCall<ReqT, RespT> call, Metadata headers, \n      ServerCallHandler<ReqT, RespT> next) {\n    for (ServerInterceptor interceptor: interceptors) {\n      next = InternalServerInterceptors.interceptCallHandlerCreate(interceptor, next);\n    }\n    return next.startCall(call, headers);\n  }","sourceCodeStart":31,"sourceCodeEnd":67,"githubUrl":"https://github.com/grpc/grpc-java/blob/64daddc1f3d1975670f769f3e97bde8b2ba32d25/authz/src/main/java/io/grpc/authz/AuthorizationServerInterceptor.java#L31-L67","documentation":"AuthorizationServerInterceptor's private constructor calls AuthorizationPolicyTranslator.translate(policy) and validates the returned RBAC list. A valid translation yields 1 RBAC (allow-only policy) or 2 RBACs (deny + allow). If translate() returns null, empty, or more than 2 entries, the constructor throws IllegalArgumentException indicating the policy failed to translate — a sanity guard against an unexpected translator output.","triggerScenarios":"Constructing AuthorizationServerInterceptor via its factory methods with an authorization policy string that translate() rejects or produces an out-of-contract result for (null/empty/>2 RBACs). Typically reached through a policy string that passes initial JSON checks but yields an invalid structure.","commonSituations":"Passing a non-policy JSON object (e.g. a config object without rules) to the interceptor factory; a mismatch between library versions where the policy schema changed.","solutions":["Pass a well-formed authorization policy JSON object with \"name\" and \"allow_rules\" (plus optional \"deny_rules\")","Test the same string against AuthorizationPolicyTranslator.translate() first to see the precise validation failure","Ensure the policy follows the documented gRPC authz policy v1 schema"],"exampleFix":"// before\nServerInterceptor i = AuthorizationServerInterceptor.create(\"{}\");\n// after\nServerInterceptor i = AuthorizationServerInterceptor.create(\n    \"{\\\"name\\\": \\\"p\\\", \\\"allow_rules\\\": []}\");","handlingStrategy":"validation","validationCode":"List<RBAC> rbacs = AuthorizationPolicyTranslator.translate(policyJson);\nif (rbacs == null || rbacs.isEmpty() || rbacs.size() > 2) {\n  throw new IllegalArgumentException(\"policy translates to invalid RBAC set\");\n}","typeGuard":null,"tryCatchPattern":"try {\n  ServerInterceptor i = AuthorizationServerInterceptor.create(policyJson);\n} catch (IOException | IllegalArgumentException e) {\n  throw new IllegalStateException(\"Cannot initialize authz interceptor: \" + e.getMessage(), e);\n}","preventionTips":["Pre-validate with AuthorizationPolicyTranslator.translate() before creating the interceptor","Use the documented policy schema and examples verbatim","Pin the grpc-authz library version and test policy compatibility on upgrades"],"tags":["grpc","authz","interceptor","validation"],"backgroundTag":"schema-validation-failed","analyzedSha":"64daddc1f3d1975670f769f3e97bde8b2ba32d25","analyzedAt":"2026-09-08T06:14:57.704Z","contentChangedAt":"2026-09-08T06:14:57.704Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}