Skip to content

feat(extauth): evaluate verification CEL rules at request time#24

Open
aramase wants to merge 1 commit into
mainfrom
aramase/f/cel_verification_adapter
Open

feat(extauth): evaluate verification CEL rules at request time#24
aramase wants to merge 1 commit into
mainfrom
aramase/f/cel_verification_adapter

Conversation

@aramase

@aramase aramase commented Jun 11, 2026

Copy link
Copy Markdown
Owner

What

Wires ServiceTokenRequirement.spec.verification.rules (CEL) end-to-end. Before this PR pkg/extauth/server.go:checkVerificationRules had a placeholder loop with a comment saying "CEL rules are evaluated by the ext auth adapter in production / Full CEL evaluation will be added when we integrate with the controller" — every CEL expression was silently ignored, and the controller's validateCELRules only checked for empty strings.

After this PR:

  • New pkg/extauth/celverify subpackage that compiles CEL programs using the documented variables (txtoken, request) and evaluates them against a request-scoped context. Kept import-free of internal/controller and pkg/extauth so both sides share one compile path.
  • Server.SetVerificationRules compiles each rule's CEL programs at push time and stores the snapshot in an atomic.Pointer[[]verificationRuleSet] so request handlers swap rule sets without locking. Rules whose CEL fails to compile are dropped and logged; the rest of the snapshot still applies.
  • checkVerificationRules evaluates the compiled programs after the existing scope/tctx checks and returns a celverify.DeniedError carrying the rule's configured message — which surfaces verbatim in the PermissionDenied response.
  • ServiceTokenRequirementReconciler.validateCELRules now invokes celverify.Compile, so syntactically invalid CEL or non-bool expressions flip ConditionReady=False on the owning STR before the rule ever reaches the runtime. Mirrors what TokenPolicyReconciler does for issuance rules (PR feat(tts): stream TokenPolicy issuance rules from controller #22).

Variables exposed to CEL

Per api/v1alpha1.VerificationRule.CEL doc-comment:

  • txtoken — TxToken claims, JSON-shaped (txtoken.sub, txtoken.scope, txtoken.tctx.<key>, txtoken.rctx.<key>, etc.).
  • request — HTTP request attributes (request.path, request.method, request.headers["x-foo"]). Header keys are lower-cased to match Envoy normalisation.

Tests

  • pkg/extauth/celverify/cel_test.go: 9 unit tests covering compile success/failure, non-bool output, runtime errors, denied error propagation, first-failing-rule semantics.
  • pkg/extauth/server_test.go: 4 new end-to-end tests through Check:
    • CEL allow path with txtoken.tctx.classification in [...].
    • CEL deny path with txtoken.tctx.classification != "pii" — asserts PermissionDenied + message + rule name.
    • CEL request.method access (GET allow, DELETE deny).
    • Bad CEL in one rule is dropped without affecting other valid rules in the same snapshot.
  • internal/controller/controller_test.go: 4 new validateCELRules cases (syntax error, non-bool expression, unknown variable, empty input).

All tests pass with go test -race ./....

Out of scope / follow-ups

  • Surfacing per-rule CEL compile errors on ServiceTokenRequirement.status individually (currently bundled into one Ready=False message). Tracked separately.
  • Metrics for extauth_verification_cel_denied_total{rule}. Tracked separately.

Copilot AI review requested due to automatic review settings June 11, 2026 05:07

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR wires ServiceTokenRequirement.spec.verification.rules (CEL) end-to-end by introducing a shared CEL compile/eval path and executing verification CEL rules at ext-auth request time, with controller-side pre-validation to prevent invalid rules from reaching runtime.

Changes:

  • Added pkg/extauth/celverify to compile verification CEL rules (with txtoken / request variables) and evaluate them against request-scoped context.
  • Updated pkg/extauth/server.go to compile rules at push time, store compiled snapshots atomically, and evaluate compiled CEL during Check.
  • Updated internal/controller CEL validation to compile using celverify.Compile, plus added unit/e2e tests covering compile/eval and request-path behavior.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
pkg/extauth/server.go Compiles verification CEL at rule-push time, stores compiled snapshot atomically, evaluates CEL during request verification.
pkg/extauth/server_test.go Adds request-path tests for allow/deny, request variables, and handling of invalid CEL in snapshots.
pkg/extauth/celverify/cel.go New shared CEL compilation + evaluation implementation for verification rules.
pkg/extauth/celverify/cel_test.go Unit tests for CEL compile/eval behavior (syntax, type checks, denial semantics, runtime errors).
internal/controller/controller.go Switches verification CEL validation to compile against the shared CEL env used by runtime.
internal/controller/controller_test.go Adds tests for controller-side validation failures (syntax/type/unknown vars/empty).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread pkg/extauth/celverify/cel.go
Comment thread pkg/extauth/server.go Outdated
Comment thread pkg/extauth/server.go Outdated
@aramase aramase force-pushed the aramase/f/cel_verification_adapter branch from 76a587d to 876ed71 Compare June 11, 2026 05:19
@aramase aramase requested a review from Copilot June 11, 2026 05:30

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated 2 comments.

Comment thread pkg/extauth/server.go Outdated
Comment thread internal/controller/controller.go Outdated
ServiceTokenRequirement CEL expressions were dead code: extauth checked
required scope and tctx field presence but the CEL loop in checkVerificationRules
had no evaluator and the controller's pre-validation only checked for empty
strings.

This wires the existing CELRule type end-to-end:

- New pkg/extauth/celverify subpackage compiles rules with cel-go using the
  documented variables (txtoken, request) and evaluates them against a
  request-scoped context. Kept import-free of controller and extauth so both
  sides can share one compile path.
- Server.SetVerificationRules now compiles each rule's CEL programs at push
  time and stores the snapshot in an atomic.Pointer so request handlers swap
  rule sets without locking. Rules whose CEL fails to compile are dropped and
  logged; the rest of the snapshot still applies.
- checkVerificationRules evaluates the compiled programs after the existing
  scope/tctx checks and returns a celverify.DeniedError carrying the rule's
  configured message, which surfaces verbatim in the PermissionDenied
  response.
- The ServiceTokenRequirement reconciler's validateCELRules now invokes
  celverify.Compile, so syntactically invalid CEL or non-bool expressions
  flip ConditionReady=False on the owning STR before reaching the runtime
  (mirrors what TokenPolicyReconciler does for issuance rules).
@aramase aramase force-pushed the aramase/f/cel_verification_adapter branch from 876ed71 to 0d38e9f Compare June 11, 2026 05:54
@aramase aramase requested a review from Copilot June 11, 2026 05:56

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated no new comments.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants