Skip to content

test: add RBAC e2e tests for create and delete endpoints#1066

Open
sradco wants to merge 1 commit into
openshift:main-alerts-management-apifrom
sradco:e2e-rbac-tests
Open

test: add RBAC e2e tests for create and delete endpoints#1066
sradco wants to merge 1 commit into
openshift:main-alerts-management-apifrom
sradco:e2e-rbac-tests

Conversation

@sradco

@sradco sradco commented Jul 20, 2026

Copy link
Copy Markdown

Summary

Depends on: #1068 (ErrSkip removal / build tags) — merge that first.

  • Adds end-to-end tests verifying Kubernetes RBAC enforcement on the management API (create and delete endpoints)
  • Three user profiles tested: unprivileged (expects 403), namespace-scoped (succeeds in own namespace, denied elsewhere), and cluster-admin (succeeds everywhere)
  • Adds framework helpers (CreateScopedUser, CreateUnprivilegedUser) for creating ServiceAccounts with specific Role/RoleBinding permissions
  • Maps Kubernetes Forbidden errors to HTTP 403 and Unauthorized to HTTP 401 in parseError (previously returned generic 500)
  • Fixes a critical bug in newUserScopedClientsets: clears client certificate fields from the copied rest.Config so the API server authenticates exclusively via the user's bearer token (client certs take precedence over bearer tokens in Kubernetes, which bypassed RBAC entirely when the base config used cert auth)
  • Includes unit tests for parseError branches and the client cert clearing behavior

Test plan

  • go test ./internal/managementrouter/... passes (unit tests for parseError)
  • go test ./pkg/k8s/... passes (unit test for client cert clearing)
  • go test -tags e2e ./test/e2e/... passes in CI with real cluster (RBAC enforcement verified)
  • go test ./... locally skips e2e entirely (no env vars needed)

Signed-off-by: Shirly Radco sradco@redhat.com

Summary by CodeRabbit

  • Bug Fixes

    • Kubernetes “Unauthorized” now returns HTTP 401 (authentication failed).
    • Kubernetes “Forbidden” now returns HTTP 403 (insufficient permissions) without leaking API details.
    • User-scoped client requests now strictly use bearer tokens, avoiding fallback to certificate-based auth.
  • Tests

    • Added/expanded unit coverage for error-to-HTTP mapping and bearer-token config behavior.
    • Added E2E RBAC coverage for alerting-rule create/delete across namespaces and permission levels.
    • E2E tests now fail fast on setup errors (no conditional skipping).
  • Chores

    • Enabled E2E-only compilation via the e2e build tag and updated the E2E test command accordingly.

@openshift-ci

openshift-ci Bot commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: sradco
Once this PR has been reviewed and has the lgtm label, please assign jan--f for approval. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@coderabbitai

coderabbitai Bot commented Jul 20, 2026

Copy link
Copy Markdown

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

The change maps Kubernetes authentication and authorization errors to HTTP 401/403 responses, forces scoped clients to use bearer tokens, adds short-lived E2E identities, and introduces alert-rule RBAC tests for create and bulk-delete operations.

Changes

RBAC authorization

Layer / File(s) Summary
Kubernetes error mapping
internal/managementrouter/router.go, internal/managementrouter/router_test.go
parseError maps Kubernetes Unauthorized and Forbidden errors to HTTP 401 and 403 responses, including wrapped errors, with table-driven coverage.
Bearer-token client and scoped identity provisioning
pkg/k8s/user_scoped_client.go, pkg/k8s/user_scoped_client_test.go, test/e2e/framework/framework.go
Scoped clients clear inherited certificate credentials; E2E helpers create short-lived ServiceAccount tokens for unprivileged and namespace-scoped users with cleanup callbacks.
Alert-rule RBAC E2E coverage and test wiring
test/e2e/rbac_test.go, test/e2e/create_alert_rule_test.go, test/e2e/delete_alert_rule_test.go, test/e2e/helpers_test.go, Makefile
Adds authorization tests for alert-rule creation and bulk deletion, gates E2E files behind the e2e build tag, and updates the E2E test command to pass that tag.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant RBACTests
  participant E2EFramework
  participant KubernetesAPI
  participant ManagementRouter

  RBACTests->>E2EFramework: Create scoped ServiceAccount identity
  E2EFramework->>KubernetesAPI: Create RBAC resources and request token
  KubernetesAPI-->>E2EFramework: Return short-lived bearer token
  RBACTests->>ManagementRouter: Send alert-rule request with token
  ManagementRouter->>KubernetesAPI: Authorize alert-rule operation
  KubernetesAPI-->>ManagementRouter: Allow or return Unauthorized/Forbidden
  ManagementRouter-->>RBACTests: Return operation status
Loading

Suggested reviewers: etmurasaki, peteryurkovich

🚥 Pre-merge checks | ✅ 15
✅ Passed checks (15 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: adding RBAC E2E tests for create and delete endpoints.
Docstring Coverage ✅ Passed Docstring coverage is 80.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Stable And Deterministic Test Names ✅ Passed Modified tests use static t.Run names; no Ginkgo It/Describe/Context/When titles or dynamic identifiers appear in the diff.
Test Structure And Quality ✅ Passed PASS: The PR uses table-driven testing subtests, adds cleanup for created users/namespaces, and uses bounded polling; no Ginkgo-style issues found.
Microshift Test Compatibility ✅ Passed New e2e tests are plain Go tests and only use namespaces, ServiceAccounts, RBAC, and PrometheusRule CRDs; no banned MicroShift-only OpenShift APIs or skips found.
Single Node Openshift (Sno) Test Compatibility ✅ Passed PASS: The new e2e tests are plain API/RBAC checks with no node-count, scheduling, HA, or topology-skip assumptions, and no Ginkgo topology guards are present.
Topology-Aware Scheduling Compatibility ✅ Passed Only tests/helpers and error-mapping code changed; no manifests/controllers or topology-sensitive scheduling constraints were introduced.
Ote Binary Stdout Contract ✅ Passed Changed files only add test/helper functions; no init/TestMain/BeforeSuite/main stdout writes or fmt.Print/log.SetOutput violations were found.
Ipv6 And Disconnected Network Test Compatibility ✅ Passed No IPv4 literals, localhost, public hosts, or raw host:port URL interpolation found; e2e requests use url.JoinPath and cluster-internal K8s/PLUGIN_URL only.
No-Weak-Crypto ✅ Passed No MD5/SHA1/DES/RC4/3DES/Blowfish/ECB, custom crypto, or secret/token comparisons were introduced in the touched code.
Container-Privileges ✅ Passed Touched files are Go helpers/tests only; no manifest changes or privileged/hostNetwork/hostIPC/SYS_ADMIN/allowPrivilegeEscalation settings were found.
No-Sensitive-Data-In-Logs ✅ Passed No new log statements emit bearer tokens, passwords, or other secrets; logs only include synthetic test IDs/namespaces and generic error bodies.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@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

🧹 Nitpick comments (3)
test/e2e/rbac_test.go (2)

201-202: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Fixed sleep for cache sync is flaky.

time.Sleep(5 * time.Second) is a fixed guess at how long the "relabeled rules cache" takes to sync. Under load this could be flaky (test proceeds before sync completes) or unnecessarily slow. Consider polling with a bounded retry/timeout (e.g., repeatedly attempt the first delete and back off) instead of a hardcoded sleep.

🤖 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 `@test/e2e/rbac_test.go` around lines 201 - 202, Replace the fixed time.Sleep
in the relabeled rules cache synchronization flow with bounded polling and retry
backoff, using the first delete attempt as the readiness check. Stop when the
delete succeeds or the retry timeout is reached, while preserving the test’s
existing failure behavior after exhaustion.

19-105: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Consider table-driven structure for repeated user/namespace test cases.

Both TestRBAC_CreateAlertRule and TestRBAC_DeleteAlertRule repeat near-identical t.Run blocks per user (A/B/C) that only differ in token, namespace/rule, and expected status. As per coding guidelines, **/*_test.go should "use table-driven tests when feasible." A slice of {name, token, target, wantStatus} cases iterated with t.Run would reduce duplication and make it easier to add new RBAC scenarios.

Also applies to: 107-241

🤖 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 `@test/e2e/rbac_test.go` around lines 19 - 105, Refactor
TestRBAC_CreateAlertRule and TestRBAC_DeleteAlertRule to use table-driven cases
for the repeated user/namespace scenarios. Define each case with its name,
token, target namespace/rule, and expected HTTP status, then iterate with t.Run
while preserving the existing assertions and scenario coverage.

Source: Coding guidelines

test/e2e/framework/framework.go (1)

261-264: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Duplicated TokenRequest construction.

The expSeconds := int64(3600) / TokenRequest construction is duplicated verbatim between CreateScopedUser and CreateUnprivilegedUser. Consider extracting a small shared helper (e.g. f.createServiceAccountToken(ctx, namespace, name)) to avoid drift between the two.

Also applies to: 289-292

🤖 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 `@test/e2e/framework/framework.go` around lines 261 - 264, Extract the
duplicated expSeconds and authv1.TokenRequest construction from CreateScopedUser
and CreateUnprivilegedUser into a shared helper such as
createServiceAccountToken, accepting the context, namespace, and service-account
name. Update both callers to use the helper while preserving their existing
token request behavior.
🤖 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 `@test/e2e/framework/framework.go`:
- Around line 224-278: Update CreateScopedUser and CreateUnprivilegedUser to
roll back resources created before any subsequent API call fails. Reuse or
invoke cleanup logic for the ServiceAccount, Role, and RoleBinding as applicable
before returning errors from Role, RoleBinding, or CreateToken operations,
including the SA-only rollback in CreateUnprivilegedUser. Preserve existing
error wrapping and successful provisioning behavior.

In `@test/e2e/rbac_test.go`:
- Line 34: Handle all flagged deferred cleanup calls in the affected test
functions and helpers, including cleanupY, cleanupZ, userA.Cleanup,
userB.Cleanup, and resp.Body.Close. Explicitly discard or log each returned
error using the project’s established pattern so errcheck passes, while
preserving the existing defer behavior.

---

Nitpick comments:
In `@test/e2e/framework/framework.go`:
- Around line 261-264: Extract the duplicated expSeconds and authv1.TokenRequest
construction from CreateScopedUser and CreateUnprivilegedUser into a shared
helper such as createServiceAccountToken, accepting the context, namespace, and
service-account name. Update both callers to use the helper while preserving
their existing token request behavior.

In `@test/e2e/rbac_test.go`:
- Around line 201-202: Replace the fixed time.Sleep in the relabeled rules cache
synchronization flow with bounded polling and retry backoff, using the first
delete attempt as the readiness check. Stop when the delete succeeds or the
retry timeout is reached, while preserving the test’s existing failure behavior
after exhaustion.
- Around line 19-105: Refactor TestRBAC_CreateAlertRule and
TestRBAC_DeleteAlertRule to use table-driven cases for the repeated
user/namespace scenarios. Define each case with its name, token, target
namespace/rule, and expected HTTP status, then iterate with t.Run while
preserving the existing assertions and scenario coverage.
🪄 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: Repository YAML (base), Central YAML (inherited)

Review profile: CHILL

Plan: Enterprise

Run ID: 4023d351-5886-44ad-8253-460e6697a620

📥 Commits

Reviewing files that changed from the base of the PR and between 6810f45 and 87d724b.

📒 Files selected for processing (4)
  • internal/managementrouter/router.go
  • internal/managementrouter/router_test.go
  • test/e2e/framework/framework.go
  • test/e2e/rbac_test.go

Comment thread test/e2e/framework/framework.go
Comment thread test/e2e/rbac_test.go Outdated
@sradco
sradco force-pushed the e2e-rbac-tests branch 4 times, most recently from 7f804d6 to b35d3f1 Compare July 20, 2026 10:29

@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: 1

🤖 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 `@Makefile`:
- Around line 61-63: Update the Makefile target declarations so unit-test
depends on test-backend, while test-backend alone owns the go test recipe. Keep
both targets phony and ensure invoking either target does not duplicate backend
test execution.
🪄 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: Repository YAML (base), Central YAML (inherited)

Review profile: CHILL

Plan: Enterprise

Run ID: 5c1aba6a-9392-41c4-a5b6-b0fe1d508daa

📥 Commits

Reviewing files that changed from the base of the PR and between 87d724b and b35d3f1.

📒 Files selected for processing (8)
  • Makefile
  • internal/managementrouter/router.go
  • internal/managementrouter/router_test.go
  • test/e2e/create_alert_rule_test.go
  • test/e2e/delete_alert_rule_test.go
  • test/e2e/framework/framework.go
  • test/e2e/helpers_test.go
  • test/e2e/rbac_test.go
🚧 Files skipped from review as they are similar to previous changes (4)
  • internal/managementrouter/router_test.go
  • test/e2e/framework/framework.go
  • internal/managementrouter/router.go
  • test/e2e/rbac_test.go

Comment thread Makefile Outdated
@sradco

sradco commented Jul 20, 2026

Copy link
Copy Markdown
Author

/test images
/test e2e-management-api
/test e2e-monitoring

@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: 1

🤖 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 `@pkg/k8s/user_scoped_client_test.go`:
- Around line 23-40: Extend the test around newUserScopedClientsets to inspect
the derived rest.Config, not just confirm base remains unchanged. Extract the
config-building logic or inject a client factory, then assert the derived config
uses “user-token” and clears CertData, KeyData, CertFile, and KeyFile while
preserving the existing base-config immutability checks.
🪄 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: Repository YAML (base), Central YAML (inherited)

Review profile: CHILL

Plan: Enterprise

Run ID: a89992f7-5fd2-4755-b411-fe27a7ed01e9

📥 Commits

Reviewing files that changed from the base of the PR and between b35d3f1 and ae13724.

📒 Files selected for processing (10)
  • Makefile
  • internal/managementrouter/router.go
  • internal/managementrouter/router_test.go
  • pkg/k8s/user_scoped_client.go
  • pkg/k8s/user_scoped_client_test.go
  • test/e2e/create_alert_rule_test.go
  • test/e2e/delete_alert_rule_test.go
  • test/e2e/framework/framework.go
  • test/e2e/helpers_test.go
  • test/e2e/rbac_test.go
🚧 Files skipped from review as they are similar to previous changes (7)
  • internal/managementrouter/router_test.go
  • test/e2e/helpers_test.go
  • test/e2e/delete_alert_rule_test.go
  • internal/managementrouter/router.go
  • test/e2e/framework/framework.go
  • test/e2e/create_alert_rule_test.go
  • test/e2e/rbac_test.go

Comment thread pkg/k8s/user_scoped_client_test.go Outdated
@sradco
sradco force-pushed the e2e-rbac-tests branch 2 times, most recently from 78f6450 to 70b220b Compare July 20, 2026 14:16
@openshift-ci openshift-ci Bot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Jul 20, 2026
@openshift-ci openshift-ci Bot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Jul 20, 2026
@sradco
sradco force-pushed the e2e-rbac-tests branch 3 times, most recently from 7cad5e7 to bf55e26 Compare July 20, 2026 15:18

@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

🧹 Nitpick comments (1)
pkg/k8s/user_scoped_client_test.go (1)

9-64: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Good fix — now asserts on the derived config directly.

This addresses the prior feedback: it now verifies cfg.BearerToken, TLSClientConfig clearing, and Insecure/Host preservation on the derived config, in addition to base-config immutability.

One gap: buildUserScopedConfig (context snippet) only clears CertData/CertFile/KeyData/KeyFile, leaving CAData/CAFile untouched — worth asserting those are preserved too, since a future regression that also strips CA verification data would silently break TLS trust to the API server and this test wouldn't catch it.

♻️ Suggested additional assertions
 	if !cfg.TLSClientConfig.Insecure {
 		t.Error("derived Insecure should be preserved as true")
 	}
+	if !bytes.Equal(cfg.TLSClientConfig.CAData, base.TLSClientConfig.CAData) {
+		t.Error("derived CAData should be preserved for server verification")
+	}
 	if cfg.Host != base.Host {
 		t.Errorf("derived Host = %q, want %q", cfg.Host, base.Host)
 	}
🤖 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 `@pkg/k8s/user_scoped_client_test.go` around lines 9 - 64, Extend
TestBuildUserScopedConfig to assert that the derived cfg preserves the base
TLSClientConfig CAData and CAFile values. Initialize those fields in the base
configuration with representative values, then verify cfg.TLSClientConfig.CAData
and CAFile remain unchanged while the client certificate and key fields are
cleared.
🤖 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 `@pkg/k8s/user_scoped_client.go`:
- Around line 20-28: Update buildUserScopedConfig to create the copied
configuration through rest.AnonymousClientConfig(baseConfig) before assigning
BearerToken, ensuring username/password, auth and exec providers, impersonation,
and custom transports or wrappers are removed while preserving the existing TLS
credential clearing.

In `@test/e2e/rbac_test.go`:
- Line 248: Wrap the deferred resp.Body.Close() calls in tryDeleteAlertRule and
createAlertRuleWithToken with the repository’s accepted error-handling pattern
so errcheck passes at both sites.

---

Nitpick comments:
In `@pkg/k8s/user_scoped_client_test.go`:
- Around line 9-64: Extend TestBuildUserScopedConfig to assert that the derived
cfg preserves the base TLSClientConfig CAData and CAFile values. Initialize
those fields in the base configuration with representative values, then verify
cfg.TLSClientConfig.CAData and CAFile remain unchanged while the client
certificate and key fields are cleared.
🪄 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: Repository YAML (base), Central YAML (inherited)

Review profile: CHILL

Plan: Enterprise

Run ID: 66dfa17a-3fc6-49cd-9957-860325add327

📥 Commits

Reviewing files that changed from the base of the PR and between ae13724 and 7cad5e7.

📒 Files selected for processing (10)
  • Makefile
  • internal/managementrouter/router.go
  • internal/managementrouter/router_test.go
  • pkg/k8s/user_scoped_client.go
  • pkg/k8s/user_scoped_client_test.go
  • test/e2e/create_alert_rule_test.go
  • test/e2e/delete_alert_rule_test.go
  • test/e2e/framework/framework.go
  • test/e2e/helpers_test.go
  • test/e2e/rbac_test.go
🚧 Files skipped from review as they are similar to previous changes (7)
  • test/e2e/helpers_test.go
  • internal/managementrouter/router_test.go
  • internal/managementrouter/router.go
  • test/e2e/delete_alert_rule_test.go
  • test/e2e/create_alert_rule_test.go
  • Makefile
  • test/e2e/framework/framework.go

Comment thread pkg/k8s/user_scoped_client.go
Comment thread test/e2e/rbac_test.go Outdated

@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)
pkg/k8s/user_scoped_client.go (1)

21-27: 🔒 Security & Privacy | 🟠 Major

Use rest.AnonymousClientConfig to make this bearer-token-only.

rest.CopyConfig preserves inherited Username/Password, AuthProvider, ExecProvider, impersonation, and custom transports/wrappers. Clearing only certificate fields does not prevent the client from authenticating as the base identity, so these scoped clients can still bypass the user’s RBAC. Start from rest.AnonymousClientConfig(baseConfig) before assigning BearerToken.

This repeats an unresolved finding from the previous review.

#!/bin/bash
set -eu

CLIENT_GO_DIR="$(go list -m -f '{{.Dir}}' k8s.io/client-go)"
rg -n -C5 \
  'func AnonymousClientConfig|func CopyConfig|AuthProvider|ExecProvider|WrapTransport|Impersonate' \
  "$CLIENT_GO_DIR/rest"
🤖 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 `@pkg/k8s/user_scoped_client.go` around lines 21 - 27, Update the config
initialization in the user-scoped client constructor to use
rest.AnonymousClientConfig(baseConfig) instead of rest.CopyConfig(baseConfig),
then assign the user BearerToken while retaining the existing certificate-field
clearing. Ensure inherited credentials, providers, impersonation, and transport
wrappers are excluded so authentication is bearer-token-only.
🤖 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 `@pkg/k8s/user_scoped_client.go`:
- Around line 21-27: Update the config initialization in the user-scoped client
constructor to use rest.AnonymousClientConfig(baseConfig) instead of
rest.CopyConfig(baseConfig), then assign the user BearerToken while retaining
the existing certificate-field clearing. Ensure inherited credentials,
providers, impersonation, and transport wrappers are excluded so authentication
is bearer-token-only.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Central YAML (inherited)

Review profile: CHILL

Plan: Enterprise

Run ID: 09ce9ecb-37a7-44e8-9436-e3671321ee9e

📥 Commits

Reviewing files that changed from the base of the PR and between 7cad5e7 and c959fab.

📒 Files selected for processing (10)
  • Makefile
  • internal/managementrouter/router.go
  • internal/managementrouter/router_test.go
  • pkg/k8s/user_scoped_client.go
  • pkg/k8s/user_scoped_client_test.go
  • test/e2e/create_alert_rule_test.go
  • test/e2e/delete_alert_rule_test.go
  • test/e2e/framework/framework.go
  • test/e2e/helpers_test.go
  • test/e2e/rbac_test.go
🚧 Files skipped from review as they are similar to previous changes (8)
  • internal/managementrouter/router_test.go
  • test/e2e/helpers_test.go
  • pkg/k8s/user_scoped_client_test.go
  • internal/managementrouter/router.go
  • test/e2e/create_alert_rule_test.go
  • test/e2e/framework/framework.go
  • test/e2e/delete_alert_rule_test.go
  • test/e2e/rbac_test.go

@sradco
sradco force-pushed the e2e-rbac-tests branch 4 times, most recently from 9497b5d to 9fe95bf Compare July 21, 2026 13:43
@PeterYurkovich

Copy link
Copy Markdown
Contributor

/retest

@sradco

sradco commented Jul 21, 2026

Copy link
Copy Markdown
Author

/test e2e-monitoring

3 similar comments
@sradco

sradco commented Jul 21, 2026

Copy link
Copy Markdown
Author

/test e2e-monitoring

@sradco

sradco commented Jul 22, 2026

Copy link
Copy Markdown
Author

/test e2e-monitoring

@sradco

sradco commented Jul 22, 2026

Copy link
Copy Markdown
Author

/test e2e-monitoring

@PeterYurkovich

Copy link
Copy Markdown
Contributor

/override ci/prow/e2e-monitoring

@openshift-ci

openshift-ci Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

@PeterYurkovich: Overrode contexts on behalf of PeterYurkovich: ci/prow/e2e-monitoring

Details

In response to this:

/override ci/prow/e2e-monitoring

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

Comment thread internal/managementrouter/router.go Outdated
Comment thread test/e2e/framework/framework.go
Comment thread test/e2e/framework/framework.go Outdated
return &ScopedUser{Token: token, Cleanup: func() error { rollback(); return nil }}, nil
}

// CreateUnprivilegedUser creates a ServiceAccount with no RBAC permissions.

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) anonymous rather than unprivileged?

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.

Updated.

Comment thread test/e2e/rbac_test.go Outdated
Comment thread test/e2e/rbac_test.go Outdated
Comment thread internal/managementrouter/router.go
Comment thread test/e2e/framework/framework.go
Comment thread test/e2e/framework/framework.go
Comment thread test/e2e/delete_alert_rule_test.go
Comment thread test/e2e/delete_alert_rule_test.go
Comment thread test/e2e/delete_alert_rule_test.go
}
defer func() { _ = userA.Cleanup() }()

userB, err := f.CreateScopedUser(ctx, "e2e-rbac-del-b", nsY,

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.

Suggested change
userB, err := f.CreateScopedUser(ctx, "e2e-rbac-del-b", nsY,
userScopedToNamespaceY, err := f.CreateScopedUser(ctx, "e2e-rbac-del-b", nsY,

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.

Updated.

Comment thread test/e2e/delete_alert_rule_test.go
Comment thread test/e2e/delete_alert_rule_test.go
@openshift-ci openshift-ci Bot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Jul 23, 2026
delete endpoints

Add e2e tests verifying that the management
API enforces Kubernetes RBAC for create and
delete alert rule operations. Three user
profiles are tested: unprivileged (expects
403), namespace-scoped (succeeds in own
namespace, denied elsewhere), and
cluster-admin (succeeds everywhere).

Also fixes a critical bug in
newUserScopedClientsets: when the base
rest.Config uses client certificates
(common in CI kubeconfigs), CopyConfig
preserved them. Since Kubernetes
authenticates via client certs when both
certs and bearer token are present, user
RBAC was bypassed entirely. Use
AnonymousClientConfig to strip all auth
so the API server authenticates exclusively
via the user's bearer token.

Signed-off-by: Shirly Radco <sradco@redhat.com>
Co-authored-by: AI Assistant <noreply@cursor.com>
@openshift-ci openshift-ci Bot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Jul 23, 2026
@PeterYurkovich

Copy link
Copy Markdown
Contributor

/override-sticky ci/prow/e2e-monitoring

@openshift-ci

openshift-ci Bot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

@PeterYurkovich: Overrode contexts on behalf of PeterYurkovich: ci/prow/e2e-monitoring

These overrides will persist across retests on the current HEAD SHA. Pushing a new commit will clear them. Use /override-cancel to remove them.

Details

In response to this:

/override-sticky ci/prow/e2e-monitoring

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

@openshift-ci

openshift-ci Bot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

@sradco: all tests passed!

Full PR test history. Your PR dashboard.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here.

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.

3 participants