fix(e2e): grant cross-namespace RBAC for Polaris dashboard proxy access #122

Closed
privilegedescalation-engineer[bot] wants to merge 1 commits from gandalf/fix-e2e-polaris-rbac into main
2 changed files with 34 additions and 0 deletions
+27
View File
@@ -44,3 +44,30 @@ roleRef:
kind: Role
name: e2e-ci-runner
apiGroup: rbac.authorization.k8s.io
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: e2e-ci-runner
namespace: polaris
rules:
# E2E Headlamp needs to proxy to the Polaris dashboard service to fetch audit results.
# The service account in privilegedescalation-dev is granted get+proxy on polaris-dashboard.
- apiGroups: [""]
resources: ["services/proxy"]
verbs: ["get"]
resourceNames: ["polaris-dashboard"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: e2e-ci-runner-binding
namespace: polaris
subjects:
- kind: ServiceAccount
name: runners-privilegedescalation-gha-rs-no-permission
namespace: arc-runners
roleRef:
kind: Role
name: e2e-ci-runner
apiGroup: rbac.authorization.k8s.io
greptile-apps[bot] commented 2026-04-27 01:18:23 +00:00 (Migrated from github.com)
Review

P1 Wrong ServiceAccount bound — fix won't resolve the root cause

The new RoleBinding in the polaris namespace binds runners-privilegedescalation-gha-rs-no-permission in arc-runners — the GHA CI runner — but the PR description identifies the actual failing identity as the in-cluster Headlamp pod, which runs as the headlamp-e2e ServiceAccount in privilegedescalation-dev. The CI runner never makes proxy calls to polaris-dashboard; the Headlamp pod does. Granting the CI runner SA this permission will not fix the 503 / Polaris dashboard not reachable E2E failure.

The subjects block should reference the Headlamp SA instead:

subjects:
  - kind: ServiceAccount
    name: headlamp-e2e          # the SA used by the Headlamp deployment (E2E_RELEASE)
    namespace: privilegedescalation-dev

(If multiple SAs are needed — e.g. headlamp-e2e-test for token auth — they can each be listed as a separate subject.)

Prompt To Fix With AI
This is a comment left during a code review.
Path: deployment/e2e-ci-runner-rbac.yaml
Line: 62-73

Comment:
**Wrong ServiceAccount bound — fix won't resolve the root cause**

The new `RoleBinding` in the `polaris` namespace binds `runners-privilegedescalation-gha-rs-no-permission` in `arc-runners` — the GHA CI runner — but the PR description identifies the actual failing identity as the in-cluster Headlamp pod, which runs as the `headlamp-e2e` ServiceAccount in `privilegedescalation-dev`. The CI runner never makes proxy calls to `polaris-dashboard`; the Headlamp pod does. Granting the CI runner SA this permission will not fix the `503 / Polaris dashboard not reachable` E2E failure.

The `subjects` block should reference the Headlamp SA instead:

```yaml
subjects:
  - kind: ServiceAccount
    name: headlamp-e2e          # the SA used by the Headlamp deployment (E2E_RELEASE)
    namespace: privilegedescalation-dev
```

(If multiple SAs are needed — e.g. `headlamp-e2e-test` for token auth — they can each be listed as a separate subject.)

How can I resolve this? If you propose a fix, please make it concise.
<a href="#"><img alt="P1" src="https://greptile-static-assets.s3.amazonaws.com/badges/p1.svg?v=7" align="top"></a> **Wrong ServiceAccount bound — fix won't resolve the root cause** The new `RoleBinding` in the `polaris` namespace binds `runners-privilegedescalation-gha-rs-no-permission` in `arc-runners` — the GHA CI runner — but the PR description identifies the actual failing identity as the in-cluster Headlamp pod, which runs as the `headlamp-e2e` ServiceAccount in `privilegedescalation-dev`. The CI runner never makes proxy calls to `polaris-dashboard`; the Headlamp pod does. Granting the CI runner SA this permission will not fix the `503 / Polaris dashboard not reachable` E2E failure. The `subjects` block should reference the Headlamp SA instead: ```yaml subjects: - kind: ServiceAccount name: headlamp-e2e # the SA used by the Headlamp deployment (E2E_RELEASE) namespace: privilegedescalation-dev ``` (If multiple SAs are needed — e.g. `headlamp-e2e-test` for token auth — they can each be listed as a separate subject.) <details><summary>Prompt To Fix With AI</summary> `````markdown This is a comment left during a code review. Path: deployment/e2e-ci-runner-rbac.yaml Line: 62-73 Comment: **Wrong ServiceAccount bound — fix won't resolve the root cause** The new `RoleBinding` in the `polaris` namespace binds `runners-privilegedescalation-gha-rs-no-permission` in `arc-runners` — the GHA CI runner — but the PR description identifies the actual failing identity as the in-cluster Headlamp pod, which runs as the `headlamp-e2e` ServiceAccount in `privilegedescalation-dev`. The CI runner never makes proxy calls to `polaris-dashboard`; the Headlamp pod does. Granting the CI runner SA this permission will not fix the `503 / Polaris dashboard not reachable` E2E failure. The `subjects` block should reference the Headlamp SA instead: ```yaml subjects: - kind: ServiceAccount name: headlamp-e2e # the SA used by the Headlamp deployment (E2E_RELEASE) namespace: privilegedescalation-dev ``` (If multiple SAs are needed — e.g. `headlamp-e2e-test` for token auth — they can each be listed as a separate subject.) How can I resolve this? If you propose a fix, please make it concise. ````` </details>
+7
View File
@@ -39,6 +39,13 @@ if ! kubectl auth can-i delete configmaps -n "$E2E_NAMESPACE" --quiet 2>/dev/nul
exit 1
fi
echo "Checking RBAC for Polaris dashboard proxy access..."
if ! kubectl auth can-i get services/proxy -n polaris --quiet 2>/dev/null; then
echo "WARNING: Missing RBAC — cannot proxy to polaris-dashboard in namespace 'polaris'." >&2
echo " E2E tests that depend on Polaris data may fail." >&2
echo " Apply the polaris namespace RBAC: kubectl apply -f deployment/e2e-ci-runner-rbac.yaml" >&2
fi
greptile-apps[bot] commented 2026-04-27 01:18:24 +00:00 (Migrated from github.com)
Review

P1 Pre-flight check tests the CI runner's identity, not the Headlamp pod's

kubectl auth can-i without --as checks whether the current kubectl context (the GHA CI runner) can get services/proxy. Since the new RoleBinding now grants that permission to the CI runner SA, this check will always pass — even though the Headlamp pod's SA (headlamp-e2e in privilegedescalation-dev) may still be missing the permission. The warning will never fire when it actually matters.

The check should impersonate the Headlamp service account:

echo "Checking RBAC for Polaris dashboard proxy access..."
if ! kubectl auth can-i get services/proxy -n polaris \
    --as="system:serviceaccount:${E2E_NAMESPACE}:${E2E_RELEASE}" --quiet 2>/dev/null; then
  echo "WARNING: Missing RBAC — cannot proxy to polaris-dashboard in namespace 'polaris'." >&2
  echo "  E2E tests that depend on Polaris data may fail." >&2
  echo "  Apply the polaris namespace RBAC: kubectl apply -f deployment/e2e-ci-runner-rbac.yaml" >&2
fi

This also makes the check consistent with the E2E_RELEASE variable already used for the Headlamp deployment's ServiceAccount name.

Prompt To Fix With AI
This is a comment left during a code review.
Path: scripts/deploy-e2e-headlamp.sh
Line: 42-47

Comment:
**Pre-flight check tests the CI runner's identity, not the Headlamp pod's**

`kubectl auth can-i` without `--as` checks whether the current kubectl context (the GHA CI runner) can get `services/proxy`. Since the new `RoleBinding` now grants that permission to the CI runner SA, this check will always pass — even though the Headlamp pod's SA (`headlamp-e2e` in `privilegedescalation-dev`) may still be missing the permission. The warning will never fire when it actually matters.

The check should impersonate the Headlamp service account:

```suggestion
echo "Checking RBAC for Polaris dashboard proxy access..."
if ! kubectl auth can-i get services/proxy -n polaris \
    --as="system:serviceaccount:${E2E_NAMESPACE}:${E2E_RELEASE}" --quiet 2>/dev/null; then
  echo "WARNING: Missing RBAC — cannot proxy to polaris-dashboard in namespace 'polaris'." >&2
  echo "  E2E tests that depend on Polaris data may fail." >&2
  echo "  Apply the polaris namespace RBAC: kubectl apply -f deployment/e2e-ci-runner-rbac.yaml" >&2
fi
```

This also makes the check consistent with the `E2E_RELEASE` variable already used for the Headlamp deployment's ServiceAccount name.

How can I resolve this? If you propose a fix, please make it concise.
<a href="#"><img alt="P1" src="https://greptile-static-assets.s3.amazonaws.com/badges/p1.svg?v=7" align="top"></a> **Pre-flight check tests the CI runner's identity, not the Headlamp pod's** `kubectl auth can-i` without `--as` checks whether the current kubectl context (the GHA CI runner) can get `services/proxy`. Since the new `RoleBinding` now grants that permission to the CI runner SA, this check will always pass — even though the Headlamp pod's SA (`headlamp-e2e` in `privilegedescalation-dev`) may still be missing the permission. The warning will never fire when it actually matters. The check should impersonate the Headlamp service account: ```suggestion echo "Checking RBAC for Polaris dashboard proxy access..." if ! kubectl auth can-i get services/proxy -n polaris \ --as="system:serviceaccount:${E2E_NAMESPACE}:${E2E_RELEASE}" --quiet 2>/dev/null; then echo "WARNING: Missing RBAC — cannot proxy to polaris-dashboard in namespace 'polaris'." >&2 echo " E2E tests that depend on Polaris data may fail." >&2 echo " Apply the polaris namespace RBAC: kubectl apply -f deployment/e2e-ci-runner-rbac.yaml" >&2 fi ``` This also makes the check consistent with the `E2E_RELEASE` variable already used for the Headlamp deployment's ServiceAccount name. <details><summary>Prompt To Fix With AI</summary> `````markdown This is a comment left during a code review. Path: scripts/deploy-e2e-headlamp.sh Line: 42-47 Comment: **Pre-flight check tests the CI runner's identity, not the Headlamp pod's** `kubectl auth can-i` without `--as` checks whether the current kubectl context (the GHA CI runner) can get `services/proxy`. Since the new `RoleBinding` now grants that permission to the CI runner SA, this check will always pass — even though the Headlamp pod's SA (`headlamp-e2e` in `privilegedescalation-dev`) may still be missing the permission. The warning will never fire when it actually matters. The check should impersonate the Headlamp service account: ```suggestion echo "Checking RBAC for Polaris dashboard proxy access..." if ! kubectl auth can-i get services/proxy -n polaris \ --as="system:serviceaccount:${E2E_NAMESPACE}:${E2E_RELEASE}" --quiet 2>/dev/null; then echo "WARNING: Missing RBAC — cannot proxy to polaris-dashboard in namespace 'polaris'." >&2 echo " E2E tests that depend on Polaris data may fail." >&2 echo " Apply the polaris namespace RBAC: kubectl apply -f deployment/e2e-ci-runner-rbac.yaml" >&2 fi ``` This also makes the check consistent with the `E2E_RELEASE` variable already used for the Headlamp deployment's ServiceAccount name. How can I resolve this? If you propose a fix, please make it concise. ````` </details>
echo "=== E2E Headlamp Deployment ==="
echo " Image: ghcr.io/headlamp-k8s/headlamp:${HEADLAMP_VERSION}"
echo " Namespace: $E2E_NAMESPACE"