Skip to content

feat: migrating to validating admission policies for our validating logic (1/)#708

Open
michaelawyu (michaelawyu) wants to merge 4 commits into
kubefleet-dev:mainfrom
michaelawyu:feat/migrate-to-vap-1
Open

feat: migrating to validating admission policies for our validating logic (1/)#708
michaelawyu (michaelawyu) wants to merge 4 commits into
kubefleet-dev:mainfrom
michaelawyu:feat/migrate-to-vap-1

Conversation

@michaelawyu
Copy link
Copy Markdown
Member

Description of your changes

This PR is the first of many following PRs to migrate to validating admission policies for applicable validation logic.

Specifically, this PR:

  • adds a admission policy manager for managing admission policies when the agent starts up. This manager is best used for environments where policies cannot be easily deployed/refreshed as part of the agent Helm charts.
  • adds two policy generator: one for denying writes to pods + replica sets in non-reserved namespaces, the other one for denying writes to service accounts and creating token requests in reserved namespaces.

Releated to #707.

I have:

  • [*] Associated this change with a known KubeFleet Issue (Bug, Feature, etc).
  • [*] Run make reviewable to ensure this PR is ready for review.

How has this code been tested

  • [*] Integration tests

Special notes for your reviewer

Signed-off-by: michaelawyu <chenyu1@microsoft.com>
Signed-off-by: michaelawyu <chenyu1@microsoft.com>
@michaelawyu
Copy link
Copy Markdown
Member Author

Please note that for this PR the manager is not enabled in the hub agent yet.

To control the PR size, additional tests will be submitted as a separate PR.

@codecov
Copy link
Copy Markdown

codecov Bot commented May 13, 2026

Codecov Report

❌ Patch coverage is 66.35514% with 108 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
pkg/admissionpolicymanager/manager.go 46.42% 68 Missing and 22 partials ⚠️
...kg/admissionpolicymanager/svcaccountsntokenreqs.go 83.52% 8 Missing and 6 partials ⚠️
pkg/admissionpolicymanager/podsnreplicasets.go 93.93% 2 Missing and 2 partials ⚠️

📢 Thoughts on this report? Let us know!

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

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 introduces the first slice of work to move KubeFleet's validation logic from validating webhooks to Kubernetes ValidatingAdmissionPolicies (VAP). It adds a startup-time policy manager that reconciles a configurable set of generated VAPs and their bindings, plus two initial generators (deny pod/replicaset writes outside reserved namespaces, deny serviceaccount/token writes in reserved namespaces). It also exports the namespace prefix constants from pkg/utils.

Changes:

  • New pkg/admissionpolicymanager package: manager that create-or-updates and garbage-collects VAPs labeled by Fleet, with two generators (pods/replicasets, serviceaccounts/tokenrequests).
  • Integration test suite (envtest) validating the manager produces the expected VAP/VAPB objects (effects deferred to E2E).
  • Exports KubePrefix, FleetPrefix, FleetMemberNamespacePrefix from pkg/utils/common.go for reuse in the generator configs.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 15 comments.

Show a summary per file
File Description
pkg/utils/common.go Exports previously unexported namespace prefix constants so the admission policy generator configs can reuse them.
pkg/admissionpolicymanager/manager.go Core policy manager: reflection-based generator selection, create-or-update with retry, GC of orphan policies/bindings via label selector.
pkg/admissionpolicymanager/configs.go Top-level configuration struct exposing per-generator config and a default.
pkg/admissionpolicymanager/podsnreplicasets.go Generator producing a VAP that denies CREATE of pods/replicasets outside reserved namespaces.
pkg/admissionpolicymanager/svcaccountsntokenreqs.go Generator producing a VAP that denies serviceaccount CRUD and tokenrequest CREATE in reserved namespaces, with user/group whitelist.
pkg/admissionpolicymanager/suite_test.go Ginkgo/envtest suite bootstrap; starts the policy manager once.
pkg/admissionpolicymanager/manager_integration_test.go Asserts the expected VAP and VAPB objects exist with correct spec/labels.

Comment thread pkg/admissionpolicymanager/svcaccountsntokenreqs.go
Comment thread pkg/admissionpolicymanager/svcaccountsntokenreqs.go
Comment thread pkg/admissionpolicymanager/podsnreplicasets.go
Comment thread pkg/admissionpolicymanager/podsnreplicasets.go Outdated
Comment thread pkg/admissionpolicymanager/manager.go
Comment thread pkg/utils/common.go Outdated
Comment on lines +102 to +132
// Exempt whitelisted users from this admission policy.
for _, username := range g.WhitelistedUsernames {
celExprAccSegs = append(celExprAccSegs, fmt.Sprintf(`request.userInfo.username == "%s"`, username))
}
// Exempt whitelisted user groups from this admission policy.
for _, userGroup := range g.WhitelistedUserGroups {
celExprAccSegs = append(celExprAccSegs, fmt.Sprintf(`"%s" in request.userInfo.groups`, userGroup))
}
// Exempt requests from the Kubernetes scheduler, any of the nodes, and (esp.) the
// Kubernetes controller manager from this admission policy.
//
// Important: the Kubernetes controller manager, when deployed with the option
// --use-service-account-credentials=true, creates a service account token for many of its controllers
// and uses those tokens to authenticate to the Kubernetes API server. It retrieves a token
// via the TokenRequest API; failure to exempt this scenario may lead to critical errors.
celExprAccSegs = append(celExprAccSegs, fmt.Sprintf(`request.userInfo.username == "%s"`, kubeSchedulerUserName))
celExprAccSegs = append(celExprAccSegs, fmt.Sprintf(`request.userInfo.username == "%s"`, kubeControllerManagerUserName))
celExprAccSegs = append(celExprAccSegs, fmt.Sprintf(`"%s" in request.userInfo.groups`, kubeNodeUserGroup))
// Exempt requests from admin users from this admission policy.
celExprAccSegs = append(celExprAccSegs, fmt.Sprintf(`"%s" in request.userInfo.groups`, adminUserGroup))

celExprAcc := strings.Join(celExprAccSegs, " || ")

celExprNSSegs := []string{}
for _, prefix := range g.ReservedNamespacePrefixes {
celExprNSSegs = append(celExprNSSegs, fmt.Sprintf(`object.metadata.namespace.startsWith("%s")`, prefix))
}
celExprNS := strings.Join(celExprNSSegs, " || ")

celExpr := fmt.Sprintf("!(%s) || (%s)", celExprNS, celExprAcc)

Copy link
Copy Markdown
Member Author

@michaelawyu michaelawyu (michaelawyu) May 18, 2026

Choose a reason for hiding this comment

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

Note: this restriction is added in consistency with our existing webhook setup. system:masters is supposed to have unlimited access to all resources BTW.

Comment on lines +119 to +121
// The error message has been set to match with the checks in some of the E2E tests
// in our existing release pipeline.
Message: "creating pods and replicas is disallowed in the fleet hub cluster",
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

N/A: as mentioned, the error msg is explicitly kept in the same style as some of the existing checks for releasing purposes.

Comment thread pkg/admissionpolicymanager/podsnreplicasets.go Outdated
Comment thread pkg/admissionpolicymanager/manager_integration_test.go
Signed-off-by: michaelawyu <chenyu1@microsoft.com>
Signed-off-by: michaelawyu <chenyu1@microsoft.com>
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