Validate GitRepo defaults from GitRepoRestriction and Policy against allow-lists#5285
Validate GitRepo defaults from GitRepoRestriction and Policy against allow-lists#5285p-se wants to merge 3 commits into
Conversation
Defaults like defaultServiceAccount and defaultClientSecretName were applied via isAllowed's fallback before being checked against the allow-list, silently accepting disallowed values. Resolve defaults first, then validate — consistent with HelmOp and Bundle paths.
Defaults are now resolved by the caller before validation, so the defaultValue parameter and string return are dead code.
There was a problem hiding this comment.
Pull request overview
This PR tightens restriction enforcement for GitRepo by ensuring defaults coming from GitRepoRestriction and Policy are validated against allow-lists (matching existing HelmOp/Bundle behavior), instead of being silently accepted.
Changes:
- Resolve
serviceAccount/clientSecretNamedefaults before allow-list validation so disallowed defaults are rejected. - Simplify
isAllowedto a validation-only helper (no defaulting), and adjust call sites accordingly. - Update/add unit tests to cover the “default not in allow-list is denied” behavior for GitRepoRestriction.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| internal/cmd/controller/gitops/reconciler/restrictions.go | Apply defaults before allow-list checks; refactor allow-list helper to validate-only. |
| internal/cmd/controller/gitops/reconciler/restrictions_test.go | Update defaulting test data and add coverage for rejecting disallowed defaults (GitRepoRestriction path). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| }, | ||
| expectedErr: "disallowed clientSecretName.*", | ||
| }, | ||
| { |
There was a problem hiding this comment.
Those test are exercising the same path as GRR is to be removed eventually, it does make sense to have tests that cover Policy to make sure those aren't lost when GRR is removed.
|
|
||
| repo, err := isAllowedByRepo(gitrepo.Spec.Repo, grr.AllowedRepoPatterns, pol.GitAllowedRepoPatterns) | ||
| if err != nil { | ||
| if _, err := isAllowedByRepo(gitrepo.Spec.Repo, grr.AllowedRepoPatterns, pol.GitAllowedRepoPatterns); err != nil { |
There was a problem hiding this comment.
nit: isAllowedByRepo seems to only be used here, so we could refactor it to return a single value.
| // Apply defaults before validation, so a default that is not in the allow-list | ||
| // is rejected rather than silently accepted. This keeps the GitRepo path | ||
| // consistent with the HelmOp and Bundle paths. | ||
| serviceAccount := firstNonEmpty(gitrepo.Spec.ServiceAccount, defaultSA) |
There was a problem hiding this comment.
nit: if the target namespace validation fails, we don't even need to compute these.
- isAllowedByRepo returns only an error; the repo string it returned was always the input and discarded at the sole call site. - Add standalone Policy cases covering defaultServiceAccount and defaultClientSecretName rejected against non-empty allow-lists, so the Policy path stays covered once GitRepoRestriction is removed.
When a
GitRepoRestriction(orPolicy) defines adefaultServiceAccountthat is not contained in a non-emptyallowedServiceAccounts(and likewisedefaultClientSecretNamevsallowedClientSecretNames), the GitRepo reconciler applies the default togitrepo.specand persists it before that value is validated against the allow-list. The disallowed value is validated only on the following reconcile, once it is an explicit spec field, and the GitRepo is rejected then.This is inconsistent with the HelmOp and Bundle paths, which validate defaults before applying them.
Steps to reproduce
Apply the restriction, then the GitRepo, and inspect it.
Expected
The GitRepo is rejected without
spec.serviceAccountbeing modified;metadata.generationstays1.Actual
spec.serviceAccountis set tosome-default-sa,metadata.generationbecomes2, and only then is the GitRepo rejected (Accepted=False,PolicyViolationevent).Refers to #5422
Additional Information
Checklist