Skip to content

[ON HOLD - CODE FREEZE] feat: Convert auth policy reconciler to TypedAction format#2007

Open
philbrookes wants to merge 4 commits into
mainfrom
gh-1996
Open

[ON HOLD - CODE FREEZE] feat: Convert auth policy reconciler to TypedAction format#2007
philbrookes wants to merge 4 commits into
mainfrom
gh-1996

Conversation

@philbrookes

@philbrookes philbrookes commented May 27, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Replace legacy wasm.Action with wasm.TypedAction for auth policies. The auth action is now a type:"grpc" TypedAction with a CheckRequest messageBuilder, onReply handlers (deny/fail/store/headers/fail), and grpcService/grpcMethod on the auth service config.
  • Add Path and Value fields to TypedAction for the store action type used in auth's onReply chain (dynamic metadata from Authorino).
  • Add ValidateTypedAction for CEL validation of typed actions (validates top-level predicate, skips onReply predicates which reference wasm-shim runtime variables).
  • Update both Istio and Envoy Gateway extension reconcilers to collect auth TypedActions separately from legacy Actions, validate them, and pass both to BuildActionSetsForPath.
  • Always create the upstream EnvoyFilter (descriptor service cluster) even without extensions, since the DynamicService for auth requires proto descriptors.

Closes #1996

Test plan

  • make test-unit — all tests pass
  • make run-lint — no lint issues
  • Unit tests for buildWasmTypedActionsForAuth, buildAuthOnReply, buildAuthMessageBuilder, joinPredicates, and JSON round-trip
  • End-to-end test on local Kind cluster with Istio: AuthPolicy with API key auth returns 200 with correct credentials via the new TypedAction format
  • Verified Authorino receives correct CheckRequest with headers, context_extensions, and metadata_context via debug logs

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Typed WASM auth actions added (including store/fail kinds) with gRPC auth support and runtime validation; validated typed actions are now included in WASM configuration.
  • Behaviour Changes

    • Reconcilers continue building upstream/patch objects even when no upstreams are discovered; action merging and validation now consider both untyped and typed actions.
  • Tests

    • New and updated unit/integration tests for typed auth actions, predicates, on-reply flows and JSON round-trips.

Review Change Stack

Replace legacy wasm.Action with wasm.TypedAction for auth policies.
The auth action is now a type:"grpc" TypedAction with a CheckRequest
messageBuilder, onReply handlers (deny/fail/store/headers/fail), and
grpcService/grpcMethod on the auth service config.

Closes #1996

Signed-off-by: Phil Brookes <pbrookes@redhat.com>

rh-pre-commit.version: 2.3.2
rh-pre-commit.check-secrets: ENABLED
@coderabbitai

coderabbitai Bot commented May 27, 2026

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

Converts auth policy WASM action generation to typed gRPC actions with on-reply decision sequences, adds TypedAction Path/Value fields and equality/tests, validates typed-action CEL predicates, and propagates validated typed actions through gateway and Istio reconcilers into wasm action-set construction; tests updated.

Changes

Auth policy WASM typed action conversion

Layer / File(s) Summary
TypedAction schema extension for store/fail actions
internal/wasm/types.go, internal/wasm/types_test.go
TypedAction adds Path and Value; EqualTo compares them; JSON round-trip and equality tests added for store actions.
CEL validation for typed actions
internal/cel/kuadrant_validator.go
Adds ValidateTypedAction to validate predicates on wasm.TypedAction when present (skips on-reply predicates); adds NewTypedActionIssue mapping action.Service to policy kind.
Auth workflow typed action construction and helpers
internal/controller/auth_workflow_helpers.go, internal/controller/auth_workflow_helpers_test.go
Replaces untyped builder with buildWasmTypedActionsForAuth; adds authResponseVar, joinPredicates, buildAuthMessageBuilder, buildAuthOnReply; on-reply sequence implements deny/fail/store/headers/fallback logic; comprehensive unit tests added.
WASM utilities for typed action propagation
internal/wasm/utils.go
BuildActionSetsForPath signature extended to accept typedActions and populate ActionSet.TypedActions for HTTP and gRPC routes.
Envoy gateway reconciler typed action integration
internal/controller/envoy_gateway_extension_reconciler.go
Accumulates typedActions from auth policies, merges their SourcePolicyLocators for tracing, validates typed actions, updates early-exit checks, and passes both validated untyped and typed actions to wasm.BuildActionSetsForPath.
Envoy gateway reconciler tests
tests/envoygateway/extension_reconciler_test.go
Updates test assertions to read auth info from ActionSets[].TypedActions and validate Service + SourcePolicyLocators for merge/atomic/override scenarios.
Istio extension reconciler typed action integration and upstream handling
internal/controller/istio_extension_reconciler.go
Mirrors gateway changes for typed actions and validation; removes early return so upstream EnvoyFilter reconciliation runs even when no upstreams discovered.
Istio reconciler tests
tests/istio/extension_reconciler_test.go
Adjusts integration tests to expect single action sets in some routes and to read auth data from TypedActions, updating service and SourcePolicyLocators assertions.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested labels

kind/enhancement

Suggested reviewers

  • adam-cattermole
  • crstrn13
  • guicassolato

Poem

"🐇 I hopped through predicates and bytes,
gRPC echoes and on-reply lights,
store the metadata, deny the wrong,
typed actions dance in orderly song,
tests clap softly — the build takes flight."

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 5.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Linked Issues check ✅ Passed The PR successfully implements all coding requirements from issue #1996: TypedAction format for auth policies with grpc type, CEL validation, Path/Value fields, and reconciler updates to handle both TypedActions and legacy actions.
Out of Scope Changes check ✅ Passed All changes are directly aligned with the stated objectives of migrating auth policies to TypedAction format and updating reconcilers accordingly, with no unrelated modifications detected.
Title check ✅ Passed The title accurately describes the main change: converting auth policy reconciler to use TypedAction format, which is the primary objective reflected across all modified files.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch gh-1996

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov

codecov Bot commented May 27, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 86.86131% with 18 lines in your changes missing coverage. Please review.
✅ Project coverage is 74.98%. Comparing base (65068c9) to head (8f9e11b).
⚠️ Report is 6 commits behind head on main.

Files with missing lines Patch % Lines
internal/cel/kuadrant_validator.go 36.36% 6 Missing and 1 partial ⚠️
...l/controller/envoy_gateway_extension_reconciler.go 62.50% 2 Missing and 4 partials ⚠️
internal/controller/istio_extension_reconciler.go 68.75% 2 Missing and 3 partials ⚠️
Additional details and impacted files
@@           Coverage Diff            @@
##             main    #2007    +/-   ##
========================================
  Coverage   74.97%   74.98%            
========================================
  Files         127      127            
  Lines       12515    12630   +115     
========================================
+ Hits         9383     9470    +87     
- Misses       2650     2670    +20     
- Partials      482      490     +8     
Flag Coverage Δ
bare-k8s-integration 20.15% <0.00%> (-0.19%) ⬇️
controllers-integration 54.33% <83.21%> (+0.50%) ⬆️
envoygateway-integration 41.42% <71.53%> (+0.37%) ⬆️
gatewayapi-integration 16.07% <0.00%> (-0.08%) ⬇️
istio-integration 45.20% <70.80%> (+0.20%) ⬆️
unit 28.69% <62.04%> (+0.45%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Components Coverage Δ
api (u) 85.88% <ø> (ø)
internal (u) 76.42% <86.86%> (-0.01%) ⬇️
pkg (u) 37.95% <ø> (ø)
Files with missing lines Coverage Δ
internal/controller/auth_workflow_helpers.go 97.26% <100.00%> (+3.05%) ⬆️
internal/wasm/types.go 84.83% <100.00%> (+1.10%) ⬆️
internal/wasm/utils.go 79.51% <100.00%> (+0.10%) ⬆️
internal/controller/istio_extension_reconciler.go 78.98% <68.75%> (-0.39%) ⬇️
...l/controller/envoy_gateway_extension_reconciler.go 72.31% <62.50%> (-0.69%) ⬇️
internal/cel/kuadrant_validator.go 75.32% <36.36%> (-6.50%) ⬇️

... and 11 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@internal/controller/auth_workflow_helpers.go`:
- Around line 116-124: The function joinPredicates should preserve each
predicate's internal boolean grouping by parenthesizing every predicate before
combining; update joinPredicates to map over predicates and wrap each entry with
"(" + predicate + ")", then join those wrapped predicates with " && " (and still
return "" for len==0). Refer to function joinPredicates and the current use of
strings.Join when making this change.

In `@internal/controller/envoy_gateway_extension_reconciler.go`:
- Around line 415-417: The new gRPC auth TypedAction built by
buildWasmTypedActionsForAuth (driven by effectiveAuthPoliciesMap/pathID)
requires the kuadrant-operator-grpc descriptor cluster, but
reconcileUpstreamClusters currently skips buildUpstreamEnvoyPatchPolicy when
gatewayUpstreams is empty; update reconcileUpstreamClusters to detect when auth
TypedActions are present (or when effectiveAuthPoliciesMap is non-empty) and
invoke buildUpstreamEnvoyPatchPolicy (or otherwise add the
kuadrant-operator-grpc cluster) even if gatewayUpstreams is empty so the
descriptor cluster is reconciled whenever auth TypedActions are emitted.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: ee57d40e-c869-42a2-8aae-97af87e6942d

📥 Commits

Reviewing files that changed from the base of the PR and between eb15622 and 85ce7b8.

📒 Files selected for processing (8)
  • internal/cel/kuadrant_validator.go
  • internal/controller/auth_workflow_helpers.go
  • internal/controller/auth_workflow_helpers_test.go
  • internal/controller/envoy_gateway_extension_reconciler.go
  • internal/controller/istio_extension_reconciler.go
  • internal/wasm/types.go
  • internal/wasm/types_test.go
  • internal/wasm/utils.go

Comment thread internal/controller/auth_workflow_helpers.go
Comment thread internal/controller/envoy_gateway_extension_reconciler.go
Wrap each predicate in parentheses before joining with && to preserve
correct boolean semantics when predicates contain || operators.

Remove len(gatewayUpstreams) == 0 guard in EnvoyGateway reconciler so
the proto descriptor cluster is always created, matching the Istio
reconciler fix.

Update integration tests for both Istio and EnvoyGateway to assert
auth actions on TypedActions instead of legacy Actions.

Signed-off-by: Phil Brookes <pbrookes@redhat.com>

rh-pre-commit.version: 2.3.2
rh-pre-commit.check-secrets: ENABLED

@coderabbitai coderabbitai Bot 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.

🧹 Nitpick comments (1)
tests/envoygateway/extension_reconciler_test.go (1)

521-524: ⚡ Quick win

Make auth typed-action assertions deterministic

Line 521 (and equivalent blocks below) indexes TypedActions[0] after only checking non-emptiness. If another typed action is introduced, this can assert against the wrong element. Prefer asserting exactly one auth typed action, or selecting by Service == wasm.AuthServiceName before asserting sources.

Suggested pattern
- g.Expect(existingWASMConfig.ActionSets[0].TypedActions).ToNot(BeEmpty())
- g.Expect(existingWASMConfig.ActionSets[0].TypedActions[0].SourcePolicyLocators).To(Equal([]string{
-   "authpolicy.kuadrant.io:" + gwAuthPolicyKey.String(),
- }))
+ authActions := make([]wasm.TypedAction, 0, len(existingWASMConfig.ActionSets[0].TypedActions))
+ for _, a := range existingWASMConfig.ActionSets[0].TypedActions {
+   if a.Service == wasm.AuthServiceName {
+     authActions = append(authActions, a)
+   }
+ }
+ g.Expect(authActions).To(HaveLen(1))
+ g.Expect(authActions[0].SourcePolicyLocators).To(Equal([]string{
+   "authpolicy.kuadrant.io:" + gwAuthPolicyKey.String(),
+ }))

Also applies to: 577-583, 652-655, 707-713, 781-784, 835-841, 909-912, 964-970

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/envoygateway/extension_reconciler_test.go` around lines 521 - 524, The
test currently assumes the auth typed-action is at index 0 after checking
TypedActions is non-empty; instead locate the auth action deterministically by
finding the element in existingWASMConfig.ActionSets[0].TypedActions whose
Service equals wasm.AuthServiceName (or assert there is exactly one matching
element) and then assert its SourcePolicyLocators equals
[]string{"authpolicy.kuadrant.io:" + gwAuthPolicyKey.String()}; apply the same
change to the other blocks that reference TypedActions[0] (lines around 577-583,
652-655, 707-713, 781-784, 835-841, 909-912, 964-970) to avoid brittle
index-based assertions.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@tests/envoygateway/extension_reconciler_test.go`:
- Around line 521-524: The test currently assumes the auth typed-action is at
index 0 after checking TypedActions is non-empty; instead locate the auth action
deterministically by finding the element in
existingWASMConfig.ActionSets[0].TypedActions whose Service equals
wasm.AuthServiceName (or assert there is exactly one matching element) and then
assert its SourcePolicyLocators equals []string{"authpolicy.kuadrant.io:" +
gwAuthPolicyKey.String()}; apply the same change to the other blocks that
reference TypedActions[0] (lines around 577-583, 652-655, 707-713, 781-784,
835-841, 909-912, 964-970) to avoid brittle index-based assertions.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: b3725a17-31ea-411d-b7e7-f22da4e773c0

📥 Commits

Reviewing files that changed from the base of the PR and between 85ce7b8 and 745ad32.

📒 Files selected for processing (5)
  • internal/controller/auth_workflow_helpers.go
  • internal/controller/auth_workflow_helpers_test.go
  • internal/controller/envoy_gateway_extension_reconciler.go
  • tests/envoygateway/extension_reconciler_test.go
  • tests/istio/extension_reconciler_test.go
💤 Files with no reviewable changes (1)
  • internal/controller/envoy_gateway_extension_reconciler.go
🚧 Files skipped from review as they are similar to previous changes (2)
  • internal/controller/auth_workflow_helpers.go
  • internal/controller/auth_workflow_helpers_test.go

Restore the len(gatewayUpstreams) == 0 guard in both Istio and
EnvoyGateway upstream cluster reconcilers. The guard removal was
unnecessary — auth TypedAction uses the wasm-shim's built-in auth
proto descriptors, not the descriptor service cluster.

Update integration test expectations to include GrpcService and
GrpcMethod fields on the auth service config, matching the new
service builder output.

Signed-off-by: Phil Brookes <pbrookes@redhat.com>

rh-pre-commit.version: 2.3.2
rh-pre-commit.check-secrets: ENABLED

@coderabbitai coderabbitai Bot 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.

♻️ Duplicate comments (1)
internal/controller/envoy_gateway_extension_reconciler.go (1)

194-196: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Keep reconciling the upstream patch for auth-only gateways.

This guard skips the only path that adds the kuadrant-operator-grpc descriptor cluster. buildWasmConfigs can still emit auth gRPC TypedActions when a gateway has no registered upstreams, and the stale-policy cleanup below can then delete any existing patch, so those gateways lose descriptor support at runtime.

Suggested fix
-		if len(gatewayUpstreams) == 0 {
-			continue
-		}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/controller/envoy_gateway_extension_reconciler.go` around lines 194 -
196, The current early-return that skips processing when len(gatewayUpstreams)
== 0 prevents adding the kuadrant-operator-grpc descriptor cluster for auth-only
gateways; remove or modify that guard so buildWasmConfigs and the patch apply
logic still run for gateways with zero upstreams (i.e., allow buildWasmConfigs
to emit auth gRPC TypedAction even when gatewayUpstreams is empty) and ensure
downstream stale-policy cleanup does not delete the descriptor-only patch—update
the logic around gatewayUpstreams, buildWasmConfigs, and the patch/cleanup
section to treat empty upstreams as valid for auth-only descriptor patching.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Duplicate comments:
In `@internal/controller/envoy_gateway_extension_reconciler.go`:
- Around line 194-196: The current early-return that skips processing when
len(gatewayUpstreams) == 0 prevents adding the kuadrant-operator-grpc descriptor
cluster for auth-only gateways; remove or modify that guard so buildWasmConfigs
and the patch apply logic still run for gateways with zero upstreams (i.e.,
allow buildWasmConfigs to emit auth gRPC TypedAction even when gatewayUpstreams
is empty) and ensure downstream stale-policy cleanup does not delete the
descriptor-only patch—update the logic around gatewayUpstreams,
buildWasmConfigs, and the patch/cleanup section to treat empty upstreams as
valid for auth-only descriptor patching.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 4a22c3a6-2842-42cf-83fd-024ef693171e

📥 Commits

Reviewing files that changed from the base of the PR and between 745ad32 and 954ed43.

📒 Files selected for processing (4)
  • internal/controller/envoy_gateway_extension_reconciler.go
  • internal/controller/istio_extension_reconciler.go
  • tests/envoygateway/extension_reconciler_test.go
  • tests/istio/extension_reconciler_test.go
🚧 Files skipped from review as they are similar to previous changes (2)
  • tests/envoygateway/extension_reconciler_test.go
  • internal/controller/istio_extension_reconciler.go

The GrpcService and GrpcMethod fields cause the wasm-shim to use the
DynamicService path for auth, which requires the kuadrant-operator-grpc
descriptor cluster. That cluster only exists when extensions register
upstreams, so auth-only gateways get 503 errors.

The current wasm-shim uses the static AuthTask handler based on
type: "auth", which doesn't need these fields. They should be added
in a follow-up when wasm-shim DynamicService auth support lands.

Signed-off-by: Phil Brookes <pbrookes@redhat.com>

rh-pre-commit.version: 2.3.2
rh-pre-commit.check-secrets: ENABLED
@philbrookes philbrookes moved this to Ready For Review in Kuadrant May 28, 2026
@philbrookes philbrookes self-assigned this May 28, 2026
Comment on lines -92 to +95
func buildWasmActionsForAuth(pathID string, effectivePolicy EffectiveAuthPolicy) []wasm.Action {
const authResponseVar = "auth_response"

func buildWasmTypedActionsForAuth(pathID string, effectivePolicy EffectiveAuthPolicy) []wasm.TypedAction {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

nit: I'd be tempted to just leave the name of the function still as buildWasmActionsForAuth just because we'll likely change TypedAction -> Action once we remove legacy config when all this migration is done for all things

scope := AuthConfigNameForPath(pathID)
predicate := joinPredicates(spec.Predicates.Into())
if predicate == "" {
predicate = "true"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

nit: maybe we could have a constant for the "true" cel expression or something?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Just noticed internal/extension/registry.go:1059 - predicateOrTrue. We could reuse that potentially.

@philbrookes philbrookes changed the title feat: Convert auth policy reconciler to TypedAction format [ON HOLD - CODE FREEZE] feat: Convert auth policy reconciler to TypedAction format Jun 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Ready For Review

Development

Successfully merging this pull request may close these issues.

Convert Auth policy reconciler to use new WASM plugin format

4 participants