Skip to content

feat(constraints): scope excludedNamespaces by process#4637

Open
amarkdotdev wants to merge 4 commits into
open-policy-agent:masterfrom
amarkdotdev:feat/constraint-excluded-namespaces-processes
Open

feat(constraints): scope excludedNamespaces by process#4637
amarkdotdev wants to merge 4 commits into
open-policy-agent:masterfrom
amarkdotdev:feat/constraint-excluded-namespaces-processes

Conversation

@amarkdotdev

@amarkdotdev amarkdotdev commented Jun 23, 2026

Copy link
Copy Markdown

Summary

Fixes #2161.

Adds spec.match.processes so constraint-level excludedNamespaces can be scoped to specific enforcement points (for example webhook only), allowing admission to skip excluded namespaces while audit continues to evaluate them.

Testing

  • go test ./pkg/mutation/match/... -run TestExcludedNamespacesProcessScoped

@amarkdotdev amarkdotdev requested a review from a team as a code owner June 23, 2026 19:51
Copilot AI review requested due to automatic review settings June 23, 2026 19:51

Copilot AI left a comment

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.

Pull request overview

This PR implements issue #2161 by adding a new spec.match.processes field so that a constraint's excludedNamespaces can be scoped to specific Gatekeeper enforcement points. The motivating use case is excluding a namespace from admission (webhook) while still letting audit evaluate it, preserving violation metrics/logs for exempted namespaces. It threads an EnforcementPoint through the review pipeline (webhook + audit) down to the shared match package, where a new Processes list gates whether a namespace exclusion applies for the current process.

Changes:

  • Added a Processes []string field to the shared match.Match type and excludedNamespacesAppliesToProcess logic so exclusions can be process-scoped (default/empty preserves existing behavior).
  • Propagated an EnforcementPoint value from the webhook and audit review entry points through target review structs into a process.Process used by the matcher.
  • Added a unit test for the process-scoped exclusion at the match package level.

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
pkg/mutation/match/match_types.go Declares the new Processes match field (source for generated CRD schema/deepcopy).
pkg/mutation/match/match.go Adds Process to Matchable and process-scoping logic in excludedNamespacesMatch.
pkg/mutation/match/match_test.go Unit test covering webhook-excluded vs audit-enforced behavior.
pkg/target/process.go New helper mapping an enforcement point string to a process.Process.
pkg/target/matcher.go Passes enforcementPoint into matchAny and sets Matchable.Process.
pkg/target/review.go Adds EnforcementPoint/enforcementPoint fields to review structs (gofmt alignment issue).
pkg/target/data.go Adds EnforcementPoint to AugmentedUnstructured.
pkg/target/target.go Wires EnforcementPoint into gkReview for all review inputs.
pkg/webhook/policy.go Sets WebhookEnforcementPoint on admission reviews and resultants.
pkg/audit/manager.go Sets AuditEnforcementPoint on audit reviews.

Note: the generated pkg/target/matchcrd_constant.go (constraint match schema) and pkg/mutation/match/zz_generated.deepcopy.go were not regenerated, so the new field is not exposed/copied — this is the primary blocker (see inline comment).

Comment on lines +37 to +40
// Processes scopes excludedNamespaces to specific Gatekeeper processes.
// Accepts `audit`, `webhook`, `sync`, `mutation-webhook`, or `*`.
// When omitted or set to `*`, excludedNamespaces applies to all processes.
Processes []string `json:"processes,omitempty"`

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Good catch — regenerated the manifests via controller-gen so processes is now present in the match schema (pkg/target/matchcrd_constant.go and the mutation CRDs that embed Match). Without it the API server would have pruned spec.match.processes as you noted.

Comment on lines +37 to +40
// Processes scopes excludedNamespaces to specific Gatekeeper processes.
// Accepts `audit`, `webhook`, `sync`, `mutation-webhook`, or `*`.
// When omitted or set to `*`, excludedNamespaces applies to all processes.
Processes []string `json:"processes,omitempty"`

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Added +kubebuilder:validation:Enum=audit;webhook;sync;mutation-webhook;* so invalid/typo'd process names are rejected at admission instead of silently matching nothing. Regenerated the schema accordingly.

Comment thread pkg/target/review.go
Comment on lines +19 to +22
namespace *corev1.Namespace
source types.SourceType
isAdmission bool
enforcementPoint string

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Fixed — ran gofmt; the gkReview field alignment is now correct.

Comment thread pkg/target/process.go
Comment on lines +8 to +15
func processFromEnforcementPoint(enforcementPoint string) process.Process {
switch enforcementPoint {
case util.AuditEnforcementPoint:
return process.Audit
default:
return process.Webhook
}
}

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

The core process-scoped matching is covered by TestExcludedNamespacesProcessScoped in the match package. I've also added TestProcessFromEnforcementPoint in pkg/target to cover the enforcement-point-to-process mapping directly.

@amarkdotdev amarkdotdev force-pushed the feat/constraint-excluded-namespaces-processes branch from 21454ec to f6732aa Compare June 25, 2026 07:18
Copilot AI review requested due to automatic review settings July 5, 2026 19:46
@amarkdotdev amarkdotdev force-pushed the feat/constraint-excluded-namespaces-processes branch from f6732aa to 4c7cec6 Compare July 5, 2026 19:46
@amarkdotdev

Copy link
Copy Markdown
Author

Rebased on latest master (4c7cec6). Process-scoped excludedNamespaces with kubebuilder enum validation and the review feedback from the earlier round are all still in.

Would appreciate a re-review when you have a moment. Thanks!

Copilot AI left a comment

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.

Pull request overview

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

Comment on lines +37 to +41
// Processes scopes excludedNamespaces to specific Gatekeeper processes.
// Accepts `audit`, `webhook`, `sync`, `mutation-webhook`, or `*`.
// When omitted or set to `*`, excludedNamespaces applies to all processes.
// +kubebuilder:validation:Enum=audit;webhook;sync;mutation-webhook;*
Processes []string `json:"processes,omitempty"`

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Fixed — switched to +kubebuilder:validation:items:Enum=... (same pattern as MutationApplyTo.Operations) and regenerated the match/mutation CRD schemas plus matchcrd_constant.go. The enum now lives on array items, not the array itself.

Comment on lines 23 to 30
// Matchable represent an object to be matched along with its metadata.
// +kubebuilder:object:generate=false
type Matchable struct {
Object client.Object
Namespace *corev1.Namespace
Source types.SourceType
Process process.Process
}

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Good catch — MatchWithApplyTo and the assignmetadata mutator now set Matchable.Process to process.Mutation so spec.match.processes scoping works on the mutation webhook path instead of silently no-oping with a zero value.

@amarkdotdev

Copy link
Copy Markdown
Author

Pushed follow-up addressing Copilot's latest review: item-level enum for processes (regenerated CRDs) and process.Mutation plumbed into mutation Matchable construction.

@codecov-commenter

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 73.17073% with 11 lines in your changes missing coverage. Please review.
✅ Project coverage is 44.90%. Comparing base (3350319) to head (1af0339).
⚠️ Report is 770 commits behind head on master.

Files with missing lines Patch % Lines
pkg/audit/manager.go 27.27% 8 Missing ⚠️
...mutation/mutators/assignmeta/assignmeta_mutator.go 0.00% 1 Missing ⚠️
pkg/mutation/mutators/core/mutator.go 0.00% 1 Missing ⚠️
pkg/target/target.go 66.66% 1 Missing ⚠️

❗ There is a different number of reports uploaded between BASE (3350319) and HEAD (1af0339). Click for more details.

HEAD has 1 upload less than BASE
Flag BASE (3350319) HEAD (1af0339)
unittests 2 1
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #4637      +/-   ##
==========================================
- Coverage   54.49%   44.90%   -9.59%     
==========================================
  Files         134      285     +151     
  Lines       12329    21067    +8738     
==========================================
+ Hits         6719     9461    +2742     
- Misses       5116    10799    +5683     
- Partials      494      807     +313     
Flag Coverage Δ
unittests 44.90% <73.17%> (-9.59%) ⬇️

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

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Add spec.match.processes so constraint-level namespace exclusions can
apply only to selected enforcement points such as webhook, while audit
continues to evaluate excluded namespaces.

Fixes open-policy-agent#2161.

Signed-off-by: amarkdotdev <amarkdotdev@users.noreply.github.com>
- Add +kubebuilder:validation:Enum to spec.match.processes so invalid
  process names are rejected instead of silently matching nothing
- Regenerate manifests so the processes field is present in the match
  schema (otherwise the API server prunes spec.match.processes)
- Add unit test for processFromEnforcementPoint
- gofmt alignment fix in gkReview

Signed-off-by: amarkdotdev <amarkdotdev@users.noreply.github.com>
Use items-level kubebuilder enum for processes arrays so the API server
accepts spec.match.processes values. Set Matchable.Process to
mutation-webhook in mutation mutator match paths.


Signed-off-by: amarkdotdev <amarkdotdev@users.noreply.github.com>
Signed-off-by: amarkdotdev <amarkdotdev@users.noreply.github.com>
@amarkdotdev amarkdotdev force-pushed the feat/constraint-excluded-namespaces-processes branch from 1af0339 to 36cf50e Compare July 6, 2026 20:26
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.

Processes selector for excludedNamespaces at the Constraint level

3 participants