@@ -158,13 +158,17 @@ private void assertAstDepthIsSafe(CelAbstractSyntaxTree ast, Cel cel)
158158
159159 private CelCompiledRule compileRuleImpl (
160160 CelPolicy .Rule rule , Cel ruleCel , CompilerContext compilerContext ) {
161+ // A local CEL environment used to compile a single rule. This temporary environment
162+ // is used to declare policy variables iteratively in a given policy, ensuring proper scoping
163+ // across a single / nested rule.
164+ Cel localCel = ruleCel ;
161165 ImmutableList .Builder <CelCompiledVariable > variableBuilder = ImmutableList .builder ();
162166 for (Variable variable : rule .variables ()) {
163167 ValueString expression = variable .expression ();
164168 CelAbstractSyntaxTree varAst ;
165169 CelType outputType = SimpleType .DYN ;
166170 try {
167- varAst = ruleCel .compile (expression .value ()).getAst ();
171+ varAst = localCel .compile (expression .value ()).getAst ();
168172 outputType = varAst .getResultType ();
169173 } catch (CelValidationException e ) {
170174 compilerContext .addIssue (expression .id (), e .getErrors ());
@@ -174,15 +178,15 @@ private CelCompiledRule compileRuleImpl(
174178 String variableName = variable .name ().value ();
175179 CelVarDecl newVariable =
176180 CelVarDecl .newVarDeclaration (variablesPrefix + variableName , outputType );
177- ruleCel = ruleCel .toCelBuilder ().addVarDeclarations (newVariable ).build ();
181+ localCel = localCel .toCelBuilder ().addVarDeclarations (newVariable ).build ();
178182 variableBuilder .add (CelCompiledVariable .create (variableName , varAst , newVariable ));
179183 }
180184
181185 ImmutableList .Builder <CelCompiledMatch > matchBuilder = ImmutableList .builder ();
182186 for (Match match : rule .matches ()) {
183187 CelAbstractSyntaxTree conditionAst ;
184188 try {
185- conditionAst = ruleCel .compile (match .condition ().value ()).getAst ();
189+ conditionAst = localCel .compile (match .condition ().value ()).getAst ();
186190 if (!conditionAst .getResultType ().equals (SimpleType .BOOL )) {
187191 compilerContext .addIssue (
188192 match .condition ().id (),
@@ -199,7 +203,7 @@ private CelCompiledRule compileRuleImpl(
199203 CelAbstractSyntaxTree outputAst ;
200204 ValueString output = match .result ().output ();
201205 try {
202- outputAst = ruleCel .compile (output .value ()).getAst ();
206+ outputAst = localCel .compile (output .value ()).getAst ();
203207 } catch (CelValidationException e ) {
204208 compilerContext .addIssue (output .id (), e .getErrors ());
205209 continue ;
@@ -209,7 +213,7 @@ private CelCompiledRule compileRuleImpl(
209213 break ;
210214 case RULE :
211215 CelCompiledRule nestedRule =
212- compileRuleImpl (match .result ().rule (), ruleCel , compilerContext );
216+ compileRuleImpl (match .result ().rule (), localCel , compilerContext );
213217 matchResult = Result .ofRule (nestedRule );
214218 break ;
215219 default :
@@ -221,7 +225,7 @@ private CelCompiledRule compileRuleImpl(
221225
222226 CelCompiledRule compiledRule =
223227 CelCompiledRule .create (
224- rule .id (), rule .ruleId (), variableBuilder .build (), matchBuilder .build (), cel );
228+ rule .id (), rule .ruleId (), variableBuilder .build (), matchBuilder .build (), ruleCel );
225229
226230 // Validate that all branches in the policy are reachable
227231 checkUnreachableCode (compiledRule , compilerContext );
0 commit comments