Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
65 commits
Select commit Hold shift + click to select a range
ce24c07
feat: [FEP-0001] support annotation-based placement (#829)
ytimocin Sep 22, 2026
d5fd386
interface: [FEP-0001] add APIs for stage update run APIs for placemen…
michaelawyu Sep 23, 2026
0161424
feat: support vendor-neutral hub kubeconfig authentication for member…
ssijbabu Sep 24, 2026
4a85997
test: add scheduled-to-bound coverage for TestPickBindingsToRoll (#847)
akshita317 Sep 24, 2026
70a80ca
fix: report negative label indexes without a nil wrapped error (#939)
akshita317 Sep 28, 2026
5efb5b1
chore: bump the all-others group across 1 directory with 4 updates (#…
dependabot[bot] Oct 1, 2026
80b1af9
chore: bump codecov/codecov-action from 7.1.0 to 7.1.1 (#934)
dependabot[bot] Oct 1, 2026
7ed98fb
feat: [FEP-0001] use field indexes in the new work generator (#942)
michaelawyu Oct 5, 2026
e0577e1
feat: [FEP-0001] add work applier (1/) (#911)
michaelawyu Oct 6, 2026
667eab7
docs: update security vulnerability instructions (#952)
sjwaight Oct 7, 2026
eae3cab
fix: surface unknown eviction conditions in draincluster (#767)
akshita317 Oct 7, 2026
5c87fc5
fix: preserve update run transition timestamp (#935)
britaniar Oct 8, 2026
c0d9fec
fix: preserve placement status metric timestamps (#936)
britaniar Oct 8, 2026
1daf821
feat: support before-stage tasks on the staged update delete stage (#…
Copilot Oct 8, 2026
34ce394
chore: bump step-security/harden-runner from 2.21.1 to 2.22.0 (#958)
dependabot[bot] Oct 9, 2026
f7cb7f1
chore: bump thehanimo/pr-title-checker from 1.4.3 to 2.0.0 (#956)
dependabot[bot] Oct 12, 2026
23f2bba
test: [FEP-0001] integration tests for the new work generator (with m…
michaelawyu Oct 12, 2026
72b4bef
fix: address a faulty method call in the code base caused by earlier …
michaelawyu Oct 12, 2026
a1ca751
fix: remediate Go CVEs from 2026-W42 scan (#969)
Copilot Oct 12, 2026
a65facb
feat: add resource eligibility checker (#931)
michaelawyu Oct 14, 2026
908881b
feat: [FEP-0001] add GC logic to resource snapshot manager (2/) + add…
michaelawyu Oct 14, 2026
005440a
chore: bump step-security/harden-runner from 2.22.0 to 2.22.1 (#977)
dependabot[bot] Oct 15, 2026
21319fd
chore: bump actions/upload-artifact from 7.0.1 to 7.0.2 (#978)
dependabot[bot] Oct 15, 2026
6778275
feat: [FEP-0001] implement the placement policy controller (#820)
ytimocin Oct 15, 2026
69c2dd5
feat: [FEP-0001] add new staged update run controller (1/) (#960)
michaelawyu Oct 16, 2026
c880487
feat: [FEP-0001] add IsSnapshotSyncd method to resource snapshot mana…
michaelawyu Oct 19, 2026
1cfc2af
feat: comment/test adjustments to resource eligibility check (#974)
michaelawyu Oct 19, 2026
aa08d9e
feat: add SAR authorizer for selected resource authorization (#962)
weng271190436 Oct 19, 2026
8f0b1a7
feat: [FEP-0001] rank clusters and create placement bindings (#945)
ytimocin Oct 19, 2026
4e85875
feat: [FEP-0001] report the resource revision and synchronization sta…
ytimocin Oct 19, 2026
b818a80
feat: [FEP-0001] re-queue placement policies when a resource they sel…
ytimocin Oct 19, 2026
164be7a
feat: [FEP-0001] wire the placement policy controllers into the hub a…
ytimocin Oct 19, 2026
91e7783
feat: selected resource authorization for resource placement (not wir…
weng271190436 Oct 20, 2026
267af9d
test: [FEP-0001] add e2e coverage for the placement policy controller…
ytimocin Oct 20, 2026
793b9bb
feat: set up backoff and event handler in the work applier + add addi…
michaelawyu Oct 20, 2026
0917658
feat: [FEP-0001] wire resource eligibility checker with placement res…
michaelawyu Oct 21, 2026
84cc1e5
test: [FEP-0001] add ITs (and some UTs) to the staged update run cont…
michaelawyu Oct 21, 2026
84e3641
fix: [FEP-0001] address a test setup issue in staged update run contr…
michaelawyu Oct 21, 2026
937966c
Merge commit from fork
ytimocin Oct 21, 2026
3df5d2f
docs: bump example versions to v0.3.2 (#1000)
ytimocin Oct 21, 2026
507f693
feat: [FEP-0001] run annotation-based placement in the hub agent (#983)
ytimocin Oct 22, 2026
373c720
test: [FEP-0001] add more ITs to the new work applier (#998)
michaelawyu Oct 22, 2026
7ee841c
chore: bump oss/go/microsoft/golang from 1.26.9-1 to 1.26.10-1 in /do…
dependabot[bot] Oct 22, 2026
1aa3f64
chore: bump step-security/harden-runner from 2.22.1 to 2.22.2 (#1002)
dependabot[bot] Oct 22, 2026
b4328ad
fix: [FEP-0001] report availability when the selected resources canno…
ytimocin Oct 22, 2026
3ec8dc5
test: [FEP-0001] add additional ITs/UTs to the work generator (#995)
michaelawyu Oct 22, 2026
3c49497
feat: [FEP-0001] add auto-rollout support for placement policies (#997)
michaelawyu Oct 22, 2026
4f156a6
test: [FEP-0001] check that placement policies deliver resources to m…
ytimocin Oct 22, 2026
83a5143
feat: [FEP-0001] run the auto-rollout controller in the hub agent (#1…
ytimocin Oct 22, 2026
5c6db3f
feat: wire-up resource eligibility checker for both APIs versions + d…
michaelawyu Oct 22, 2026
fe96827
feat: add VAP safeguard for the placement policy API (annotated for p…
michaelawyu Oct 22, 2026
ebf816a
test: [FEP-0001] add some E2E tests for the new placement experience …
michaelawyu Oct 22, 2026
ad8abce
test: [FEP-0001] add some E2E tests for the new placement experience …
michaelawyu Oct 25, 2026
ea2fb7e
feat: [FEP-0001] improve handling of orphaned resource snapshots (#1012)
michaelawyu Oct 25, 2026
c082455
feat: [FEP-0001] block cross-ops between the v0 and v1 placement expe…
michaelawyu Oct 26, 2026
c65dafa
feat: [FEP-0001] add resource-specific sanitization logic to the reso…
michaelawyu Oct 26, 2026
b825afe
feat: [FEP-0001] categorize NotFound errors properly when snapshottin…
michaelawyu Oct 26, 2026
d977d1b
feat: [FEP-0001] handle incomplete/missing snapshots better in the wo…
michaelawyu Oct 26, 2026
953675e
test: [FEP-0001] add more E2E tests (3/) (#1017)
michaelawyu Oct 26, 2026
32dd136
feat: [FEP-0001] apply some CRD changes (shortnames, markers, validat…
michaelawyu Oct 26, 2026
19ceaeb
feat: [FEP-0001] add flag to enable annotation-based placement experi…
michaelawyu Oct 26, 2026
e3ab57c
fix: skip the hub agent namespace in the pod and replica set webhooks…
ytimocin Oct 27, 2026
5937e37
Applied Azure-specific changes
michaelawyu Oct 27, 2026
c014db5
Minor adjustments/fixes
michaelawyu Oct 27, 2026
5cc8367
Minor adjustments/fixes
michaelawyu Oct 27, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
42 changes: 42 additions & 0 deletions .github/.copilot/breadcrumbs/2026-08-12-2353-delete-stage-tasks.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Support Before-Stage Tasks on the Delete Stage

## Overview

Allow staged update strategies to gate the delete stage with an Approval task, the same before-stage task the
update stages support, so that removing the resources from the clusters that left a placement can be held until
a sign-off is given.

## Plan

1. Add an optional `deleteStage` to the shared update strategy API, with `beforeStageTasks`.
2. Snapshot the tasks and initialize their statuses as the `beforeStageTaskStatus` of the delete stage.
3. Evaluate the tasks with the same code that evaluates the before-stage tasks of the update stages.
4. Add API validation, unit, integration and E2E coverage for both cluster-scoped and namespaced runs.
5. Regenerate API code and CRDs, then run the tests and the repository quality checks.

## Decisions

- The delete stage is configured as a stage (`deleteStage.beforeStageTasks`) rather than with a delete stage
specific task list, so that the API, the status and the approval requests use the same vocabulary as the
update stages, and so that the delete stage can take more configurations later.
- The before-stage tasks of the delete stage follow the update stages: at most one task, and it must be an
Approval. A soak time before the removal is already possible with a TimedWait in the afterStageTasks of the
last update stage, as the delete stage only starts once the last update stage, including its after-stage tasks,
completes.
- The approval request is named `<updateRun>-before-delete-stage` with the generic before-stage name format.
`delete-stage` also is the stage label value of the approval request, as the name of the delete stage,
`kubernetes-fleet.io/deleteStage`, is not a valid label value. An update stage cannot have this name.
- The tasks only gate the start of the deletion and they are skipped if there is no cluster to delete, the same
as an update stage with no clusters.
- An update run that is stopped while it waits for the tasks stops without deleting any binding.

## Success Criteria

- [x] No delete stage configuration preserves immediate deletion.
- [x] The approval must be given before any binding is deleted.
- [x] Cluster-scoped and namespaced runs keep the bindings until the tasks pass.
- [x] Generated API and CRD artifacts are current.

## Follow-ups

- Document the delete stage configuration in the staged update docs (website repository).
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Cleanup Leftover Works

## Goal

Implement `cleanupLeftOverWorks` so manifests previously applied or prepared by leftover Work objects are removed unless still referenced by the current linked Work set.

## Plan

- [x] Collect manifest identifiers whose Applied condition is true or has the preparing-to-process reason.
- [x] Exclude identifiers present in `seenManifIDs`.
- [x] Remove the collected manifests in parallel through `removeOneLeftOverManifest`.
- [x] Aggregate per-manifest failures and run focused validation.

## Success Criteria

- Current manifests are preserved.
- Only previously applied or pre-processed leftover manifests are selected.
- Selected manifests are removed through the existing ownership-aware helper in one parallel batch.

## Validation

- `gofmt` completed successfully.
- Editor diagnostics report no errors in `cleanup.go`.
- `go test ./pkg/v1/controllers/workapplier` is currently blocked by pre-existing unused `leftOverWorks` and `seenManifestIDs` variables in `controller.go`, where the surrounding cleanup call site is still unfinished.

## Placement Deletion Follow-Up

- [ ] Preserve explicit sync strategy values while applying defaults.
- [ ] Delete linked AppliedWork objects with foreground or orphan propagation according to `WhenPlacementDeleted`.
- [ ] After `foregroundDeletionWaitTime`, explicitly clean tracked manifests blocking foreground deletion.
- [ ] Remove Work cleanup finalizers only after the corresponding AppliedWork is gone.
- [ ] Wire placement and leftover cleanup into reconciliation and validate the package.
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Fix: Preserve UpdateRun Condition Transition Timestamp

## Overview

Prevent hub-agent reconciliation and restarts from restamping the UpdateRun status metric when the selected Kubernetes condition has not transitioned.

## Plan

1. Trace UpdateRun condition reconciliation and metric emission.
2. Emit the selected condition's persisted `LastTransitionTime` instead of reconciliation time.
3. Add focused unit tests for unchanged failed conditions and actual status transitions.
4. Run the smallest relevant UpdateRun unit test suite.

## Success Criteria

- [x] Re-emitting an unchanged failed condition preserves the metric timestamp.
- [x] A condition status transition emits the new transition timestamp.
- [x] Focused UpdateRun tests pass.

## Implementation Notes

- Kubernetes `meta.SetStatusCondition` already preserves `LastTransitionTime` when `Status` is unchanged and advances it when `Status` changes.
- The restamping occurred in metric emission through `SetToCurrentTime()`, independently of the persisted condition.
- `emitUpdateRunStatusMetric` now sets the gauge from the selected condition's `LastTransitionTime`.
- Added table-driven unit coverage for failed, initialized, executing, and succeeded runs. Each case emits twice to prove reconciliation does not restamp the selected condition's timestamp.
- Validation: `go test ./pkg/controllers/updaterun -run 'TestEmitUpdateRunStatusMetricUsesConditionTransitionTime|TestDetermineFailureType|TestIsFailureReason' -count=1`.
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Add Work Owner Binding Field Index

**Date**: October 2, 2026 00:01 AEST
**Task**: Add a composite field index for Work objects keyed by owner binding namespace and name.

## Requirements

1. Add the `workOwnedByBinding` custom field.
2. Format indexed values as `%s/%s`.
3. Extract the owner namespace from `WorkOwnerNamespaceLabelKey`.
4. Extract the owner binding name from `WorkOwnedByPlacementBindingLabelKey`.
5. Register the Work field extractor in `SetupWithHubControllerManager`.
6. Use the custom field index when listing Work objects by owner binding.
7. Use the existing owner-and-index custom field when listing secondary placement resource snapshots.

## Plan

1. Add exported field-name and value-format constants to `pkg/v1/utils/fieldindexers/hub.go`.
2. Add a Work owner-binding field extractor using the owner namespace and binding labels, while distinguishing a missing owner-namespace label from a valid empty cluster-scoped namespace.
3. Register the extractor for `placementv1alpha1.Work` in `SetupWithHubControllerManager`.
4. Update `listWorksByOwnerBinding` to query the composite custom field while retaining the Work namespace filter.
5. Update secondary placement resource snapshot retrieval to query the existing composite owner-and-index field.
6. Run the targeted field-indexer and workgenerator package tests and formatting.

## Decisions

1. Use the owner-binding label as the indexed binding-name source.
2. Permit an empty owner namespace only when the owner-namespace label is present, preserving support for cluster-scoped bindings.
3. Unit tests are omitted for now at the user's request.

## Status

Implementation complete.

## Validation

- `gofmt -w pkg/v1/utils/fieldindexers/hub.go pkg/v1/controllers/workgenerator/retrieval.go`
- `go test ./pkg/v1/utils/fieldindexers ./pkg/v1/controllers/workgenerator` (passed; packages currently have no test files)
- `git diff --check` (passed)
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
# Enforce selected-resource authorization

**Date**: October 8, 2026 17:29 UTC
**Task**: Prevent placement and override APIs from using Fleet's controller permissions to access resources the requester could not access directly.

## Requirements

1. Enforce selected-resource authorization for ClusterResourcePlacement, ResourcePlacement, ClusterResourceOverride, and ResourceOverride create and update requests.
2. Build SubjectAccessReview requests from the admission request's complete user information: username, UID, groups, and extras.
3. Fail closed when resource resolution or authorization cannot be completed.
4. Require `get` for resources selected by name.
5. For CRP/RP label and all-of-kind selectors, require `list` in the relevant scope, without individual `get` checks for enumerated objects.
6. For namespace selection, authorize the Namespace selection using `get` by name or `list` for label/all-of-kind selection. For NamespaceWithResources, require `list` per eligible expanded namespaced resource type, without individual `get` checks for their objects.
7. Ignore resources that begin matching dynamic selectors after admission in this implementation.
8. Require `patch` for JSONPatch overrides and `delete` for Delete overrides.
9. Require Kubernetes RBAC privilege-protection checks when overrides affect Role, ClusterRole, RoleBinding, or ClusterRoleBinding resources.
10. For CRP/RP, authorize creates and reauthorize the complete selected set on spec-changing updates, even if selectors are unchanged. Overrides retain the original every-update reauthorization requirement.
11. For CRP/RP, skip selected-resource authorization on updates with semantically unchanged specs, including label, annotation, and finalizer changes regardless of deletion state. Preserve existing validation behavior. For overrides, retain the deletion/finalizer cleanup exception.
12. Enable enforcement by default and provide a temporary feature flag to disable it.

## Plan

### Phase 1: Authorization foundation and tests

- [x] Add a selected-resource reviewer that creates Kubernetes SubjectAccessReviews and preserves all admission user information.
- [x] Add RESTMapper-based conversion from selector GVKs to the plural GVRs required by SubjectAccessReview.
- [x] Deduplicate identical checks within one authorization batch and use bounded concurrency for object-level reviews.
- [x] Add unit tests for allowed, denied, no-opinion, API-error, timeout, identity-copying, and duplicate-review cases.
- **Success criterion:** Authorization behavior is independently testable and every unresolved or unsuccessful review fails closed.

### Phase 2a: ResourcePlacement authorization (current slice)

- [x] Build RP permission checks from selectors and REST mappings without fetching source objects.
- [x] Require `get` for named selections and `list` for label/all-of-kind selections in the RP namespace.
- [x] Authorize creates and spec-changing updates; preserve existing validation and deletion cleanup behavior.
- [x] Add RP constructor, scope, selector, overlapping-review, identity, denial, and failure tests.
- **Success criterion:** RP authorization is independently testable, fails closed, and does not require live object or informer dependencies.

### Phase 2b: ClusterResourcePlacement authorization (follow-up slice)

- [ ] Add direct cluster-scoped resource authorization.
- [ ] Resolve selected Namespaces using live hub API reads.
- [ ] Add NamespaceOnly, NamespaceWithResourceSelectors, and NamespaceWithResources authorization.
- [ ] Add CRP webhook tests for namespace modes, scope, overlapping selectors, and failure cases.
- **Success criterion:** CRP authorization follows the agreed get/list policy without expanding the RP-only review scope.

### Phase 3: Override authorization

- [ ] Authorize every currently selected CRO and RO target.
- [ ] Require `patch` for JSONPatch rules, including `remove` operations on fields, and `delete` when a Delete rule removes the entire selected resource from a member cluster.
- [ ] Apply or inspect override patches sufficiently to perform correct `escalate` checks for Role/ClusterRole rule changes and `bind` checks against the resulting RoleBinding/ClusterRoleBinding role reference.
- [ ] Add CRO and RO webhook tests for patch, delete, escalate, bind, namespaced scope, update reauthorization, and fail-closed behavior.
- **Success criterion:** Overrides cannot mutate, suppress, escalate, or bind selected RBAC resources beyond the requester's direct authority.

### Phase 4: Wiring, RBAC, and rollout

- [ ] Add a default-enabled hub-agent feature flag that can temporarily disable selected-resource authorization.
- [ ] Pass the RESTMapper, uncached/live resource reader, and SAR client into all four validating webhooks.
- [ ] Grant the hub-agent service account `create` on `authorization.k8s.io/subjectaccessreviews`.
- [ ] Update directly related Helm values and user-facing flag documentation.
- **Success criterion:** Default installations enforce authorization, while operators have an explicit temporary rollback switch.

### Phase 5: Verification

- [ ] Run formatting and focused authorization, webhook, and option tests.
- [ ] Run the smallest relevant integration tests using real Kubernetes RBAC authorization.
- [ ] Add focused RP webhook authorization wiring and update-gating coverage.
- [ ] Run `make reviewable` before submission.
- [ ] Update this breadcrumb with implementation details, changed files, and validation results.
- **Success criterion:** Focused and repository-required checks pass with no authorization bypass or unrelated behavior regression.

## Decisions

1. Cover all four v1beta1 APIs in separate reviewable slices: RP first, then CRP, CRO, and RO.
2. Dynamic resources that match after admission are an acknowledged limitation and are not blocked because dynamic selection is a core Fleet feature.
3. Placement label and all-of-kind selection requires `list` only. Named selection requires `get` for the named object.
4. NamespaceWithResources authorizes the Namespace selection and requires `list` for each relevant namespaced GVR, without individual `get` checks for enumerated objects.
5. Delete overrides require `delete`; JSONPatch overrides require `patch`.
6. CRP/RP creates and spec-changing updates authorize the complete selected set using the current requester's identity. Unchanged-spec updates skip selected-resource authorization but still undergo existing validation. Override updates retain every-update reauthorization.
7. Finalizer removal during deletion bypasses selected-resource authorization.
8. Enforcement is enabled by default behind a temporary disable flag.

## Non-goals

1. Continuous reauthorization when a new resource begins matching an existing dynamic selector.
2. Persisting creator identity for controller-time authorization.
3. Replacing Kubernetes RBAC or supporting label-restricted authorization policies beyond what SubjectAccessReview reports.

## Status

Plan approved by the user. Phase 1 and the Phase 2a RP-only slice are complete on
`feat/selected-resource-authorization-phase-2`. Phase 2b and Phases 3-5 remain.
On October 19, the user requested a smaller review scope. The full implementation
is preserved in pushed commit `e640d9b2`; the follow-up slice retains RP only.

## Phase 2a implementation details

- Added `ResourcePlacementAuthorizer` and `NewResourcePlacementAuthorizer` in
`pkg/utils/authorization/placement.go`, with private mapper, reviewer, and
eligibility-checker dependencies. No reader, informer, or Namespace resolution
is needed. An explicit RP/CRP type switch routes RP to its typed resolver;
the CRP branch returns a clear not-implemented error for the follow-up slice.
- Build get checks for named selectors and list checks for label/all-of-kind
selectors in the RP namespace. No source objects are fetched. Reuse the Phase 1
reviewer's identity preservation, deduplication, and bounded concurrency.
- Use explicit Allowed, Denied, and Indeterminate decisions. Denials take
precedence over additional review errors; malformed results fail closed.
- Add an optional RP webhook authorizer through shared placement validation.
Authorize creates and spec-changing updates only. Unchanged-spec updates still
run existing validation, and the old invalid-placement deletion exception is
unchanged. Authorizer unit tests cover scope, selectors, denials, and SAR errors;
shared validator tests cover admission decision mapping. The dedicated RP
webhook authorization test file was removed at the user's request; its wiring
and update-gating coverage is deferred.
- Defer CRP authorization and its tests. Its handler passes nil to the shared
authorization parameter, preserving existing behavior. The controller's resource
selector resolver is unchanged.
- Production registration still does not inject the RP authorizer. Default-on
enforcement, rollout wiring, and SAR RBAC remain Phase 4.

## Phase 2a validation

- Focused race tests passed for `pkg/utils/authorization`, `pkg/utils/validator`,
`pkg/webhook/clusterresourceplacement`, and `pkg/webhook/resourceplacement`.
- Existing CRP webhook tests passed unchanged.
- `go vet` passed for the authorization, validator, and placement webhook packages.
- `go build ./cmd/hubagent/...` passed.
- Before committing, `make lint GOLANGCI_LINT=/home/weiweng/go/bin/golangci-lint`
passed repository-wide with the installed repository-version linter (v2.13.2).
- Repository-configured lint passed with `--new-from-rev=main`,
`--max-issues-per-linter=0`, and `--max-same-issues=0` for the affected packages.
Unfiltered package lint also reports pre-existing issues in the CRP mutating
webhook tests; these were not changed.
- `git diff --check` passed. Go commands use
`MS_GOTOOLCHAIN_ALLOW_NON_LOCAL=1 GOTOOLCHAIN=auto`, as in Phase 1.
- Full `make reviewable` and real Kubernetes RBAC integration remain Phase 5
verification, before PR submission.

## Phase 1 implementation details

- Added `pkg/utils/authorization` with a reusable, stateless batch Reviewer.
- Preserved username, UID, groups, and deep-copied extras in every SubjectAccessReview.
- Added RESTMapper-based GVK-to-GVR conversion for correctly pluralized authorization attributes.
- Deduplicated identical attributes within each authorization batch; separate calls always perform fresh reviews.
- Limited concurrent SubjectAccessReviews per request, collected results in stable input order, and recorded explicit failures for reviews not submitted after request cancellation.
- Returned structured results that aggregate explicit denials separately from joined evaluation, API, and malformed-response errors; conclusive denials take precedence while errors remain available for logging.
- Added focused unit coverage for resource mapping, identity propagation, aggregated denial and error results, timeout handling, deduplication, and bounded concurrency.

## Phase 1 validation

- `MS_GOTOOLCHAIN_ALLOW_NON_LOCAL=1 GOTOOLCHAIN=auto go test -race ./pkg/utils/authorization` passed.
- `MS_GOTOOLCHAIN_ALLOW_NON_LOCAL=1 GOTOOLCHAIN=auto go vet ./pkg/utils/authorization` passed.
- Automatic toolchain selection was required because `go.mod` requires Go 1.26.6 while the installed local Microsoft Go toolchain is 1.26.5.

## References

- `pkg/utils/validator/placement.go` - shared CRP/RP admission validation.
- `pkg/webhook/clusterresourceplacement` - CRP mutating and validating webhooks.
- `pkg/webhook/resourceplacement` - RP validating webhook.
- `pkg/webhook/clusterresourceoverride` - CRO validating webhook.
- `pkg/webhook/resourceoverride` - RO validating webhook.
- `pkg/utils/controller/resource_selector_resolver.go` - current placement selector resolution semantics.
- `cmd/hubagent/options/featureflags.go` - hub-agent feature flag conventions.
- `charts/hub-agent/templates/rbac.yaml` - hub-agent service account permissions.
- No applicable specification directory exists under `.github/.copilot/`, and no selected-resource authorization entry was found in the domain knowledge files.
Loading
Loading