Skip to content

fix(kubescape): make C-0015 secret-list exceptions take effect#2442

Merged
devantler merged 6 commits into
mainfrom
claude/kubescape-c0015-secret-reader-exception
Jul 5, 2026
Merged

fix(kubescape): make C-0015 secret-list exceptions take effect#2442
devantler merged 6 commits into
mainfrom
claude/kubescape-c0015-secret-reader-exception

Conversation

@devantler

@devantler devantler commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

🤖 Generated by the Daily AI Assistant

Why: The Kubescape control C-0015 ("List Kubernetes secrets") reports 0/50 passing — every service account that can read Secrets shows as failing, so the dashboard gives no usable signal. Its only exception sat under a namespaceSelector, which Kubescape can't apply to RBAC-based findings (they're keyed on the Role/binding, not a namespace) — so even legitimate readers like cert-manager stayed red. The repo already hit and fixed this for C-0187; C-0015 was left behind.

What: Moves C-0015 to a new exception that matches the ~65 legitimate secret-reading controllers/operators/databases by their RBAC object — the proven wildcard-rbac.yaml pattern — and mirrors it into the Headlamp exceptions ConfigMap. C-0015 becomes a meaningful signal: legitimate readers pass, and a handful of genuinely over-privileged / admin identities remain surfaced on purpose (unused tenant edit SAs, crossview's wildcard read, the cluster-admin/crossplane admin groups).

This is a scanner-suppression change only — it grants and removes no privileges. Residual flagged findings tracked in #2441.

Merge order: the posture scan is currently frozen (separate v4.0.9 regression, fixed by #2443) — this change only becomes visible on the dashboard once #2443 lands and scanning resumes. It is correct and safe to merge independently.

Note: agent-authored — needs a direct gh pr merge --squash after promotion (not auto-merge).

C-0015 ("List Kubernetes secrets") reported 0/50 passing: its only
exception sat under a namespaceSelector, which Kubescape cannot apply to
RBAC-based findings (keyed on the Role/ClusterRole/binding, not a
namespace), so every secret-reader — including legitimate ones like
cert-manager — stayed flagged.

Move C-0015 to a dedicated secret-reader-rbac.yaml matching the ~65
legitimate secret-reading controllers/operators/databases by their RBAC
object (the proven wildcard-rbac.yaml kind+name pattern), remove the inert
entry from controller-rbac.yaml, and mirror the change into the Headlamp
exceptions ConfigMap. Genuinely over-privileged/admin identities (unused
tenant `edit` SAs, crossview's wildcard read, the cluster-admin/crossplane
admin groups) are deliberately left flagged so the control keeps working.

Scanner-suppression only — grants and removes no privileges. Validated:
ksail workload validate (local + prod, 500 files each); new CSE passes the
live Kubescape CRD schema.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jul 4, 2026

Copy link
Copy Markdown

Review Change Stack

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

Walkthrough

Moves the Kubescape C-0015 posture exception out of controller-rbac into a new secret-reader-rbac manifest scoped with explicit RBAC kind and name matches. controller-rbac now keeps C-0053 and updates its RBAC scoping note. The Kustomize base includes the new manifest, and the Headlamp Kubescape exception ConfigMap is updated to mirror the split with a new secret-reader-rbac policy group.

Possibly related issues

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: making the C-0015 Kubescape secret-list exception work.
Description check ✅ Passed The description is directly related to the RBAC-based C-0015 exception update and its Headlamp mirror.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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.

Comment @coderabbitai help to get the list of available commands.

…5-secret-reader-exception

# Conflicts:
#	k8s/bases/infrastructure/cluster-security-exceptions/controller-rbac.yaml

@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.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
k8s/bases/infrastructure/controllers/kubescape/config-map-headlamp-exceptions.yaml (2)

731-758: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Crossplane provider ClusterRole names are pinned to a literal hash suffix.

Entries at lines 731-737, 738-744, 745-751, and 752-758 match attributes.name against a fixed hash (provider-aws-iam-ae66959c4138, provider-family-aws-1bcdce25f1e9, provider-upjet-github-04d509bb9f6f, provider-upjet-unifi-553bd95aeec2). These names include a generated hash that changes on provider re-installs/revisions, and attributes.name here is evaluated with regexCompare, so the exception should use an anchored regex covering the stable prefix plus hash pattern instead of the current literal hash.

Based on learnings from a prior review in this repo: "For Kubescape ClusterSecurityException ... and the mirrored Headlamp exception config, do NOT pin spec.match.resources[].name (and Headlamp attributes.name) to a single literal value when the identifier includes a generated hash ... match such resources with an anchored regular expression that covers the stable prefix and the hash pattern (e.g., ^crossplane:provider:provider-upjet-github-[0-9a-f]+:system$)."

🔧 Proposed fix
           {
             "designatorType": "Attributes",
             "attributes": {
               "kind": "^ClusterRole$",
-              "name": "^crossplane:provider:provider-aws-iam-ae66959c4138:system$"
+              "name": "^crossplane:provider:provider-aws-iam-[0-9a-f]+:system$"
             }
           },
           {
             "designatorType": "Attributes",
             "attributes": {
               "kind": "^ClusterRole$",
-              "name": "^crossplane:provider:provider-family-aws-1bcdce25f1e9:system$"
+              "name": "^crossplane:provider:provider-family-aws-[0-9a-f]+:system$"
             }
           },
           {
             "designatorType": "Attributes",
             "attributes": {
               "kind": "^ClusterRole$",
-              "name": "^crossplane:provider:provider-upjet-github-04d509bb9f6f:system$"
+              "name": "^crossplane:provider:provider-upjet-github-[0-9a-f]+:system$"
             }
           },
           {
             "designatorType": "Attributes",
             "attributes": {
               "kind": "^ClusterRole$",
-              "name": "^crossplane:provider:provider-upjet-unifi-553bd95aeec2:system$"
+              "name": "^crossplane:provider:provider-upjet-unifi-[0-9a-f]+:system$"
             }
           },
🤖 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
`@k8s/bases/infrastructure/controllers/kubescape/config-map-headlamp-exceptions.yaml`
around lines 731 - 758, The Crossplane provider ClusterRole exception entries
are pinned to exact hash-suffixed names, which can break after re-installs or
revisions. Update the affected `attributes.name` matches in the Headlamp
exception config to use anchored regex patterns with the stable provider prefix
plus a hash wildcard, following the existing `regexCompare`-style matching used
for `ClusterRole` designators. Keep the same exception entries for the
provider-aws-iam, provider-family-aws, provider-upjet-github, and
provider-upjet-unifi roles, but replace each literal hash suffix with a flexible
pattern so the match survives regenerated names.

Source: Learnings


520-989: 🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

Mirror the Crossplane provider matchers here with anchored regexes — these entries still hardcode the full provider names, so new hash suffixes will fall out of the exception list unless this CR stays in lockstep with the ConfigMap.

🤖 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
`@k8s/bases/infrastructure/controllers/kubescape/config-map-headlamp-exceptions.yaml`
around lines 520 - 989, The secret-reader-rbac exception list in the kubescape
config map is too specific for Crossplane provider roles, so new provider hash
suffixes will stop matching. Update the Crossplane-related resource matchers in
the secret-reader-rbac policy to use anchored regex patterns that match the
provider role prefix rather than hardcoded full names, keeping the existing
exception intent while making it resilient to future provider renames. Use the
existing secret-reader-rbac policy entry and the Crossplane provider matchers as
the place to update.
🤖 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.

Outside diff comments:
In
`@k8s/bases/infrastructure/controllers/kubescape/config-map-headlamp-exceptions.yaml`:
- Around line 731-758: The Crossplane provider ClusterRole exception entries are
pinned to exact hash-suffixed names, which can break after re-installs or
revisions. Update the affected `attributes.name` matches in the Headlamp
exception config to use anchored regex patterns with the stable provider prefix
plus a hash wildcard, following the existing `regexCompare`-style matching used
for `ClusterRole` designators. Keep the same exception entries for the
provider-aws-iam, provider-family-aws, provider-upjet-github, and
provider-upjet-unifi roles, but replace each literal hash suffix with a flexible
pattern so the match survives regenerated names.
- Around line 520-989: The secret-reader-rbac exception list in the kubescape
config map is too specific for Crossplane provider roles, so new provider hash
suffixes will stop matching. Update the Crossplane-related resource matchers in
the secret-reader-rbac policy to use anchored regex patterns that match the
provider role prefix rather than hardcoded full names, keeping the existing
exception intent while making it resilient to future provider renames. Use the
existing secret-reader-rbac policy entry and the Crossplane provider matchers as
the place to update.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: f277f803-1bea-490d-8077-8ce94fbd5e2d

📥 Commits

Reviewing files that changed from the base of the PR and between ae42c3f and 9ee0e9e.

📒 Files selected for processing (3)
  • k8s/bases/infrastructure/cluster-security-exceptions/controller-rbac.yaml
  • k8s/bases/infrastructure/cluster-security-exceptions/kustomization.yaml
  • k8s/bases/infrastructure/controllers/kubescape/config-map-headlamp-exceptions.yaml
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • devantler-tech/actions (auto-detected)
  • devantler-tech/aws (auto-detected)
  • devantler-tech/reusable-workflows (auto-detected)
  • devantler-tech/ksail (auto-detected)
  • devantler-tech/ascoachingogvaner (auto-detected)
  • devantler-tech/wedding-app (auto-detected)
  • devantler-tech/agent-skills (auto-detected)
📜 Review details
⏰ Context from checks skipped due to timeout. (3)
  • GitHub Check: 🧪 Validate Manifests
  • GitHub Check: Analyze (python)
  • GitHub Check: Analyze (python)
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{yaml,yml}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{yaml,yml}: Use Kustomize overlays rather than editing base resources directly; k8s/bases/ is immutable from overlays and changes should be made with patches: in provider or cluster overlays.
Keep manifest changes small and use YAML/schema validation before submitting a manifest PR; for files with cluster context, prefer ksail workload validate / kubectl kustomize / kubectl apply --dry-run=client as appropriate.

Files:

  • k8s/bases/infrastructure/cluster-security-exceptions/kustomization.yaml
  • k8s/bases/infrastructure/cluster-security-exceptions/controller-rbac.yaml
  • k8s/bases/infrastructure/controllers/kubescape/config-map-headlamp-exceptions.yaml
k8s/**

📄 CodeRabbit inference engine (AGENTS.md)

k8s/**: Respect Flux dependency order: bootstrapinfrastructure-controllersinfrastructureapps, with the prod-only infrastructure-overprovisioning layer hanging off infrastructure without gating apps.
Follow the hierarchical Kustomization flow: base configurations in k8s/bases/ feed provider overlays in k8s/providers/, which feed cluster overlays in k8s/clusters/.

Files:

  • k8s/bases/infrastructure/cluster-security-exceptions/kustomization.yaml
  • k8s/bases/infrastructure/cluster-security-exceptions/controller-rbac.yaml
  • k8s/bases/infrastructure/controllers/kubescape/config-map-headlamp-exceptions.yaml
k8s/bases/infrastructure/**

📄 CodeRabbit inference engine (AGENTS.md)

k8s/bases/infrastructure/**: Under k8s/bases/infrastructure/, organize resources component-folder-first: a component's HelmRelease/HelmRepository and its own CRs should live together in a folder named after the component unless a split is required.
Split a custom resource into its own plural-Kind folder only when it cannot live with its component, such as for CRD dependency ordering or because it is cluster-scoped/cross-cutting.

Files:

  • k8s/bases/infrastructure/cluster-security-exceptions/kustomization.yaml
  • k8s/bases/infrastructure/cluster-security-exceptions/controller-rbac.yaml
  • k8s/bases/infrastructure/controllers/kubescape/config-map-headlamp-exceptions.yaml
k8s/bases/infrastructure/**/*.{yaml,yml}

📄 CodeRabbit inference engine (AGENTS.md)

k8s/bases/infrastructure/**/*.{yaml,yml}: For component-folder files, name manifests after the resource Kind in kebab-case; if a folder contains multiple resources of the same Kind, qualify filenames with a purpose suffix.
For CR-folder files, omit the folder-implied Kind from the filename and use the verb-purpose.yaml form.
Name Flux Kustomization resources flux-kustomization*.yaml; keep the kustomize build file named exactly kustomization.yaml.

Files:

  • k8s/bases/infrastructure/cluster-security-exceptions/kustomization.yaml
  • k8s/bases/infrastructure/cluster-security-exceptions/controller-rbac.yaml
  • k8s/bases/infrastructure/controllers/kubescape/config-map-headlamp-exceptions.yaml
🧠 Learnings (2)
📚 Learning: 2026-07-01T21:13:36.950Z
Learnt from: devantler
Repo: devantler-tech/platform PR: 2359
File: k8s/bases/apps/actual-budget/helm-release.yaml:62-111
Timestamp: 2026-07-01T21:13:36.950Z
Learning: When reviewing Kustomize/Helm YAML in this repo, keep the base vs provider overlay split: `k8s/bases/apps/**` and `k8s/bases/infrastructure/**` should contain each app’s full, environment-agnostic configuration (including base-level postRenderer Kustomize patches such as deployment strategy, topology spread, probes, and env injection). `k8s/providers/{docker,hetzner}/**` should only add small provider-specific deltas (e.g., `interval`, `persistence.size`) via patch files (like `k8s/providers/<provider>/apps/<app>/patches/helm-release-patch.yaml`). If configuration is identical across providers (e.g., OIDC/OAuth env vars where `${domain}` is resolved per cluster via envsubst), it belongs in the base and must not be duplicated into provider overlays.

Applied to files:

  • k8s/bases/infrastructure/cluster-security-exceptions/kustomization.yaml
  • k8s/bases/infrastructure/cluster-security-exceptions/controller-rbac.yaml
  • k8s/bases/infrastructure/controllers/kubescape/config-map-headlamp-exceptions.yaml
📚 Learning: 2026-07-04T13:30:04.759Z
Learnt from: devantler
Repo: devantler-tech/platform PR: 2446
File: k8s/bases/infrastructure/cluster-security-exceptions/delete-rbac.yaml:38-125
Timestamp: 2026-07-04T13:30:04.759Z
Learning: For Kubescape ClusterSecurityException (apiVersion kubescape.io/v1beta1) and the mirrored Headlamp exception config, do NOT pin `spec.match.resources[].name` (and Headlamp `attributes.name`) to a single literal value when the identifier includes a generated hash. These fields are compared using `regexCompare`, so match such resources with an anchored regular expression that covers the stable prefix and the hash pattern (e.g., `^crossplane:provider:provider-upjet-github-[0-9a-f]+:system$`) rather than the current hash, so the exception remains valid across provider re-installs/revisions.

Applied to files:

  • k8s/bases/infrastructure/cluster-security-exceptions/kustomization.yaml
  • k8s/bases/infrastructure/cluster-security-exceptions/controller-rbac.yaml
  • k8s/bases/infrastructure/controllers/kubescape/config-map-headlamp-exceptions.yaml
🔇 Additional comments (4)
k8s/bases/infrastructure/cluster-security-exceptions/controller-rbac.yaml (2)

23-35: LGTM!


36-49: LGTM!

The expanded NOTE accurately documents why RBAC-object controls can't be suppressed via namespaceSelector and correctly cross-references secret-reader-rbac.yaml, consistent with that manifest's own header comment.

k8s/bases/infrastructure/cluster-security-exceptions/kustomization.yaml (1)

6-9: LGTM!

secret-reader-rbac.yaml is correctly registered and keeps the resource list alphabetically ordered.

Also applies to: 15-15

k8s/bases/infrastructure/controllers/kubescape/config-map-headlamp-exceptions.yaml (1)

73-76: LGTM!

Correctly mirrors controller-rbac.yaml's updated posture list (C-0015 replaced by C-0053).

@devantler

Copy link
Copy Markdown
Contributor Author

🤖 Generated by the Daily AI Assistant

CodeRabbit review-body resolution record (⚠️ Outside diff range, 2 findings — no threads exist for them): both valid and fixed in e602406 + bfe0171. The four Crossplane provider ClusterRole matchers no longer pin the generated revision hash — they now use the anchored pattern ^crossplane:provider:provider-<name>-[0-9a-f]+:system$ in both surfaces (the Headlamp exceptions ConfigMap and the secret-reader-rbac ClusterSecurityException), so a provider re-install/revision bump can't silently drop them out of the C-0015 exception. Embedded JSON re-validated; both files YAML-parse.

@devantler

Copy link
Copy Markdown
Contributor Author

🤖 Generated by the Daily AI Assistant

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 4, 2026

Copy link
Copy Markdown

@devantler I'll review the changes now.

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@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.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
k8s/bases/infrastructure/cluster-security-exceptions/secret-reader-rbac.yaml (1)

61-269: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Anchor the literal Kubescape matchers. spec.match.resources[].name is regex-based, so unanchored literals like operator, longhorn, and flux-operator can overmatch future RBAC objects and suppress C-0015 unintentionally. Add ^...$ around the non-regex names here and leave the intentionally regex-shaped entries unchanged.

🤖 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 `@k8s/bases/infrastructure/cluster-security-exceptions/secret-reader-rbac.yaml`
around lines 61 - 269, The literal RBAC name matchers in the secret-reader rules
are being treated as regex patterns, so unanchored entries can overmatch and
hide unrelated resources. Update the `spec.match.resources[].name` entries in
`secret-reader-rbac.yaml` for the plain literals in this block to use exact
anchors, especially the `operator`, `longhorn`, and `flux-operator` style names,
while leaving the already regex-shaped `^crossplane:...$` entries unchanged.

Source: Learnings

🤖 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.

Outside diff comments:
In
`@k8s/bases/infrastructure/cluster-security-exceptions/secret-reader-rbac.yaml`:
- Around line 61-269: The literal RBAC name matchers in the secret-reader rules
are being treated as regex patterns, so unanchored entries can overmatch and
hide unrelated resources. Update the `spec.match.resources[].name` entries in
`secret-reader-rbac.yaml` for the plain literals in this block to use exact
anchors, especially the `operator`, `longhorn`, and `flux-operator` style names,
while leaving the already regex-shaped `^crossplane:...$` entries unchanged.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: b5579ae9-f801-40b9-9fb4-763ad793d816

📥 Commits

Reviewing files that changed from the base of the PR and between 9ee0e9e and bfe0171.

📒 Files selected for processing (2)
  • k8s/bases/infrastructure/cluster-security-exceptions/secret-reader-rbac.yaml
  • k8s/bases/infrastructure/controllers/kubescape/config-map-headlamp-exceptions.yaml
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • devantler-tech/actions (auto-detected)
  • devantler-tech/aws (auto-detected)
  • devantler-tech/reusable-workflows (auto-detected)
  • devantler-tech/ksail (auto-detected)
  • devantler-tech/ascoachingogvaner (auto-detected)
  • devantler-tech/wedding-app (auto-detected)
  • devantler-tech/agent-skills (auto-detected)
📜 Review details
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{yaml,yml}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{yaml,yml}: Use Kustomize overlays rather than editing base resources directly; k8s/bases/ is immutable from overlays and changes should be made with patches: in provider or cluster overlays.
Keep manifest changes small and use YAML/schema validation before submitting a manifest PR; for files with cluster context, prefer ksail workload validate / kubectl kustomize / kubectl apply --dry-run=client as appropriate.

Files:

  • k8s/bases/infrastructure/controllers/kubescape/config-map-headlamp-exceptions.yaml
  • k8s/bases/infrastructure/cluster-security-exceptions/secret-reader-rbac.yaml
k8s/**

📄 CodeRabbit inference engine (AGENTS.md)

k8s/**: Respect Flux dependency order: bootstrapinfrastructure-controllersinfrastructureapps, with the prod-only infrastructure-overprovisioning layer hanging off infrastructure without gating apps.
Follow the hierarchical Kustomization flow: base configurations in k8s/bases/ feed provider overlays in k8s/providers/, which feed cluster overlays in k8s/clusters/.

Files:

  • k8s/bases/infrastructure/controllers/kubescape/config-map-headlamp-exceptions.yaml
  • k8s/bases/infrastructure/cluster-security-exceptions/secret-reader-rbac.yaml
k8s/bases/infrastructure/**

📄 CodeRabbit inference engine (AGENTS.md)

k8s/bases/infrastructure/**: Under k8s/bases/infrastructure/, organize resources component-folder-first: a component's HelmRelease/HelmRepository and its own CRs should live together in a folder named after the component unless a split is required.
Split a custom resource into its own plural-Kind folder only when it cannot live with its component, such as for CRD dependency ordering or because it is cluster-scoped/cross-cutting.

Files:

  • k8s/bases/infrastructure/controllers/kubescape/config-map-headlamp-exceptions.yaml
  • k8s/bases/infrastructure/cluster-security-exceptions/secret-reader-rbac.yaml
k8s/bases/infrastructure/**/*.{yaml,yml}

📄 CodeRabbit inference engine (AGENTS.md)

k8s/bases/infrastructure/**/*.{yaml,yml}: For component-folder files, name manifests after the resource Kind in kebab-case; if a folder contains multiple resources of the same Kind, qualify filenames with a purpose suffix.
For CR-folder files, omit the folder-implied Kind from the filename and use the verb-purpose.yaml form.
Name Flux Kustomization resources flux-kustomization*.yaml; keep the kustomize build file named exactly kustomization.yaml.

Files:

  • k8s/bases/infrastructure/controllers/kubescape/config-map-headlamp-exceptions.yaml
  • k8s/bases/infrastructure/cluster-security-exceptions/secret-reader-rbac.yaml
🧠 Learnings (2)
📚 Learning: 2026-07-01T21:13:36.950Z
Learnt from: devantler
Repo: devantler-tech/platform PR: 2359
File: k8s/bases/apps/actual-budget/helm-release.yaml:62-111
Timestamp: 2026-07-01T21:13:36.950Z
Learning: When reviewing Kustomize/Helm YAML in this repo, keep the base vs provider overlay split: `k8s/bases/apps/**` and `k8s/bases/infrastructure/**` should contain each app’s full, environment-agnostic configuration (including base-level postRenderer Kustomize patches such as deployment strategy, topology spread, probes, and env injection). `k8s/providers/{docker,hetzner}/**` should only add small provider-specific deltas (e.g., `interval`, `persistence.size`) via patch files (like `k8s/providers/<provider>/apps/<app>/patches/helm-release-patch.yaml`). If configuration is identical across providers (e.g., OIDC/OAuth env vars where `${domain}` is resolved per cluster via envsubst), it belongs in the base and must not be duplicated into provider overlays.

Applied to files:

  • k8s/bases/infrastructure/controllers/kubescape/config-map-headlamp-exceptions.yaml
  • k8s/bases/infrastructure/cluster-security-exceptions/secret-reader-rbac.yaml
📚 Learning: 2026-07-04T13:30:04.759Z
Learnt from: devantler
Repo: devantler-tech/platform PR: 2446
File: k8s/bases/infrastructure/cluster-security-exceptions/delete-rbac.yaml:38-125
Timestamp: 2026-07-04T13:30:04.759Z
Learning: For Kubescape ClusterSecurityException (apiVersion kubescape.io/v1beta1) and the mirrored Headlamp exception config, do NOT pin `spec.match.resources[].name` (and Headlamp `attributes.name`) to a single literal value when the identifier includes a generated hash. These fields are compared using `regexCompare`, so match such resources with an anchored regular expression that covers the stable prefix and the hash pattern (e.g., `^crossplane:provider:provider-upjet-github-[0-9a-f]+:system$`) rather than the current hash, so the exception remains valid across provider re-installs/revisions.

Applied to files:

  • k8s/bases/infrastructure/controllers/kubescape/config-map-headlamp-exceptions.yaml
  • k8s/bases/infrastructure/cluster-security-exceptions/secret-reader-rbac.yaml
🔀 Multi-repo context devantler-tech/ksail, devantler-tech/reusable-workflows, devantler-tech/actions, devantler-tech/aws, devantler-tech/ascoachingogvaner, devantler-tech/wedding-app, devantler-tech/agent-skills

Linked repositories findings

devantler-tech/ksail [::devantler-tech/ksail::]

  • pkg/client/kubescape/client.go and pkg/client/kubescape/buildscaninfo_test.go show KSail forwards an exceptions file path directly to Kubescape via UseExceptions/--exceptions, and the contract is specifically a JSON array of PostureExceptionPolicy objects.
  • pkg/apis/cluster/v1alpha1/types.go:236-242, schemas/ksail-config.schema.json:1100, and web/ui/src/generated/ksail-config.ts:844 all document the same exceptions-file contract, so the new secret-reader-rbac.yaml must stay parseable as Kubescape native exceptions JSON/YAML.
  • pkg/cli/cmd/workload/scan.go:36-139 and pkg/cli/cmd/workload/workload_test.go:2792-2985 verify --exceptions precedence and behavior, but do not special-case C-0015; this change is consumed as data only.

Other linked repos [::devantler-tech/reusable-workflows::] [::devantler-tech/actions::] [::devantler-tech/aws::] [::devantler-tech/ascoachingogvaner::] [::devantler-tech/wedding-app::] [::devantler-tech/agent-skills::]

  • No relevant references found to C-0015, secret-reader-rbac, controller-rbac, headlamp-exceptions, ClusterSecurityException, SecurityException, or kubescape.
🔇 Additional comments (2)
k8s/bases/infrastructure/cluster-security-exceptions/secret-reader-rbac.yaml (1)

1-58: LGTM!

k8s/bases/infrastructure/controllers/kubescape/config-map-headlamp-exceptions.yaml (1)

73-76: LGTM!

Also applies to: 519-988

Kubescape matches ClusterSecurityException resource names as unanchored
regexes, so a literal like 'operator' or 'longhorn' could silently
suppress C-0015 on future RBAC objects whose names merely contain it.
Anchoring every literal (the crossplane hash entries were already
regex-shaped) also brings the CSE in line with the Headlamp mirror,
which was anchored all along.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@devantler

Copy link
Copy Markdown
Contributor Author

🤖 Generated by the Daily AI Assistant

Resolution record — CodeRabbit review-body finding (⚠️ Outside diff range, 🟠 Major, 2026-07-04 21:25Z): anchor the literal Kubescape matchers in secret-reader-rbac.yaml.

Valid — Kubescape matches spec.match.resources[].name as an unanchored regex, so literals like operator/longhorn/flux-operator could overmatch future RBAC objects and silently widen the C-0015 suppression. Fixed in the latest push: every literal name is now ^…$-anchored (the four crossplane hash entries were already regex-shaped and are unchanged). This also brings the CSE in line with the Headlamp mirror ConfigMap, which was fully anchored all along, so no mirror change was needed.

@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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
k8s/bases/infrastructure/cluster-security-exceptions/secret-reader-rbac.yaml (1)

60-269: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Consider YAML anchors to cut repetition (optional).

Nearly every entry repeats apiGroup: rbac.authorization.k8s.io plus kind: ClusterRole/kind: Role across ~70 list items. YAML anchors/merge keys could shrink this significantly, e.g.:

resources:
  - &clusterRoleMatch
    apiGroup: rbac.authorization.k8s.io
    kind: ClusterRole
    name: ^crd-controller-flux-system$
  - <<: *clusterRoleMatch
    name: ^tf-runner-role$

Purely a readability nicety; not required since this mirrors the established pattern in sibling files (e.g. wildcard-rbac.yaml).

🤖 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 `@k8s/bases/infrastructure/cluster-security-exceptions/secret-reader-rbac.yaml`
around lines 60 - 269, The RBAC allowlist in the secret-reader rules repeats the
same apiGroup and kind fields across many entries, so consider refactoring the
list with YAML anchors/merge keys in the resources block to reduce duplication
while preserving the same ClusterRole and Role name patterns. Use the existing
resource entries in this manifest as the source of truth and apply the same
pattern consistently to related symbols like the ClusterRole and Role items
without changing 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
`@k8s/bases/infrastructure/cluster-security-exceptions/secret-reader-rbac.yaml`:
- Around line 244-253: The generic Role exemptions are too broad because the
name matchers like ^operator$, ^longhorn$, ^vault-config$, and ^velero-server$
are namespace-blind in the cluster-security-exceptions config. Update the
relevant matcher entries in the secret-reader RBAC exception list to scope each
Role by namespace, using the existing Role/ClusterRole patterns in this YAML so
only the intended namespace-specific roles are exempted.

---

Outside diff comments:
In
`@k8s/bases/infrastructure/cluster-security-exceptions/secret-reader-rbac.yaml`:
- Around line 60-269: The RBAC allowlist in the secret-reader rules repeats the
same apiGroup and kind fields across many entries, so consider refactoring the
list with YAML anchors/merge keys in the resources block to reduce duplication
while preserving the same ClusterRole and Role name patterns. Use the existing
resource entries in this manifest as the source of truth and apply the same
pattern consistently to related symbols like the ClusterRole and Role items
without changing behavior.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: c26dc5e6-0b29-4951-96b7-77e911e1e204

📥 Commits

Reviewing files that changed from the base of the PR and between bfe0171 and 8e9fc59.

📒 Files selected for processing (1)
  • k8s/bases/infrastructure/cluster-security-exceptions/secret-reader-rbac.yaml
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • devantler-tech/actions (auto-detected)
  • devantler-tech/aws (auto-detected)
  • devantler-tech/reusable-workflows (auto-detected)
  • devantler-tech/ksail (auto-detected)
  • devantler-tech/ascoachingogvaner (auto-detected)
  • devantler-tech/wedding-app (auto-detected)
  • devantler-tech/agent-skills (auto-detected)
📜 Review details
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{yaml,yml}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{yaml,yml}: Use Kustomize overlays rather than editing base resources directly; k8s/bases/ is immutable from overlays and changes should be made with patches: in provider or cluster overlays.
Keep manifest changes small and use YAML/schema validation before submitting a manifest PR; for files with cluster context, prefer ksail workload validate / kubectl kustomize / kubectl apply --dry-run=client as appropriate.

Files:

  • k8s/bases/infrastructure/cluster-security-exceptions/secret-reader-rbac.yaml
k8s/**

📄 CodeRabbit inference engine (AGENTS.md)

k8s/**: Respect Flux dependency order: bootstrapinfrastructure-controllersinfrastructureapps, with the prod-only infrastructure-overprovisioning layer hanging off infrastructure without gating apps.
Follow the hierarchical Kustomization flow: base configurations in k8s/bases/ feed provider overlays in k8s/providers/, which feed cluster overlays in k8s/clusters/.

Files:

  • k8s/bases/infrastructure/cluster-security-exceptions/secret-reader-rbac.yaml
k8s/bases/infrastructure/**

📄 CodeRabbit inference engine (AGENTS.md)

k8s/bases/infrastructure/**: Under k8s/bases/infrastructure/, organize resources component-folder-first: a component's HelmRelease/HelmRepository and its own CRs should live together in a folder named after the component unless a split is required.
Split a custom resource into its own plural-Kind folder only when it cannot live with its component, such as for CRD dependency ordering or because it is cluster-scoped/cross-cutting.

Files:

  • k8s/bases/infrastructure/cluster-security-exceptions/secret-reader-rbac.yaml
k8s/bases/infrastructure/**/*.{yaml,yml}

📄 CodeRabbit inference engine (AGENTS.md)

k8s/bases/infrastructure/**/*.{yaml,yml}: For component-folder files, name manifests after the resource Kind in kebab-case; if a folder contains multiple resources of the same Kind, qualify filenames with a purpose suffix.
For CR-folder files, omit the folder-implied Kind from the filename and use the verb-purpose.yaml form.
Name Flux Kustomization resources flux-kustomization*.yaml; keep the kustomize build file named exactly kustomization.yaml.

Files:

  • k8s/bases/infrastructure/cluster-security-exceptions/secret-reader-rbac.yaml
🧠 Learnings (2)
📚 Learning: 2026-07-01T21:13:36.950Z
Learnt from: devantler
Repo: devantler-tech/platform PR: 2359
File: k8s/bases/apps/actual-budget/helm-release.yaml:62-111
Timestamp: 2026-07-01T21:13:36.950Z
Learning: When reviewing Kustomize/Helm YAML in this repo, keep the base vs provider overlay split: `k8s/bases/apps/**` and `k8s/bases/infrastructure/**` should contain each app’s full, environment-agnostic configuration (including base-level postRenderer Kustomize patches such as deployment strategy, topology spread, probes, and env injection). `k8s/providers/{docker,hetzner}/**` should only add small provider-specific deltas (e.g., `interval`, `persistence.size`) via patch files (like `k8s/providers/<provider>/apps/<app>/patches/helm-release-patch.yaml`). If configuration is identical across providers (e.g., OIDC/OAuth env vars where `${domain}` is resolved per cluster via envsubst), it belongs in the base and must not be duplicated into provider overlays.

Applied to files:

  • k8s/bases/infrastructure/cluster-security-exceptions/secret-reader-rbac.yaml
📚 Learning: 2026-07-04T13:30:04.759Z
Learnt from: devantler
Repo: devantler-tech/platform PR: 2446
File: k8s/bases/infrastructure/cluster-security-exceptions/delete-rbac.yaml:38-125
Timestamp: 2026-07-04T13:30:04.759Z
Learning: For Kubescape ClusterSecurityException (apiVersion kubescape.io/v1beta1) and the mirrored Headlamp exception config, do NOT pin `spec.match.resources[].name` (and Headlamp `attributes.name`) to a single literal value when the identifier includes a generated hash. These fields are compared using `regexCompare`, so match such resources with an anchored regular expression that covers the stable prefix and the hash pattern (e.g., `^crossplane:provider:provider-upjet-github-[0-9a-f]+:system$`) rather than the current hash, so the exception remains valid across provider re-installs/revisions.

Applied to files:

  • k8s/bases/infrastructure/cluster-security-exceptions/secret-reader-rbac.yaml
🪛 Trivy (0.69.3)
k8s/bases/infrastructure/cluster-security-exceptions/secret-reader-rbac.yaml

[info] 45-269: limit range usage

A LimitRange policy with a default requests and limits for each container should be configured

Rule: KSV-0039

Learn more

(IaC/Kubernetes)

🔀 Multi-repo context

Linked repositories findings

devantler-tech/ksail

  • schemas/ksail-config.schema.json:1098-1116 — the workload scan exceptions setting is documented as a Kubescape-native exceptions file (PostureExceptionPolicy JSON array). This means the new secret-reader-rbac.yaml must remain valid Kubescape exceptions data.
  • web/ui/src/generated/ksail-config.ts:840-846 — the generated UI config mirrors the same contract and forwards the exceptions file to kubescape --exceptions.
  • pkg/client/kubescape/buildscaninfo_test.go and pkg/client/kubescape/client.go (confirmed by the repo search results) — KSail passes the exceptions path through directly; there’s no special handling for C-0015 or ClusterSecurityException, so this PR is consumed purely as config/data.

devantler-tech/reusable-workflows, devantler-tech/actions, devantler-tech/aws, devantler-tech/ascoachingogvaner, devantler-tech/wedding-app, devantler-tech/agent-skills

  • No references found to C-0015, secret-reader-rbac, controller-rbac, headlamp-exceptions, ClusterSecurityException, PostureExceptionPolicy, or kubescape.
🔇 Additional comments (1)
k8s/bases/infrastructure/cluster-security-exceptions/secret-reader-rbac.yaml (1)

1-59: LGTM!

Also applies to: 60-165

@github-project-automation github-project-automation Bot moved this from 🫴 Ready to 🏃🏻‍♂️ In Progress in 🌊 Project Board Jul 4, 2026
…5-secret-reader-exception

# Conflicts:
#	k8s/bases/infrastructure/cluster-security-exceptions/kustomization.yaml
@devantler

Copy link
Copy Markdown
Contributor Author

🤖 Generated by the Daily AI Assistant

Resolution record — CodeRabbit review-body finding (⚠️ Outside diff range, 2026-07-04T21:47Z review): declined with reasoning.

The finding suggests YAML anchors/merge keys to cut the repeated apiGroup/kind fields in secret-reader-rbac.yaml. Declining:

  • CodeRabbit itself marks it Trivial / Low value / optional and notes it is "not required since this mirrors the established pattern in sibling files (e.g. wildcard-rbac.yaml)".
  • Consistency with the sibling CSE manifests is worth more than the byte savings — anchors in one file would diverge the suite's exception style.
  • Merge keys (<<:) are YAML 1.1-only; not every parser in the chain (kubescape's CR ingestion, kustomize, linters) guarantees identical handling, so explicit entries are the safer canonical form for security-exception manifests.

No further body findings outstanding; CodeRabbit's final review (22:21Z) is APPROVED.

@devantler devantler marked this pull request as ready for review July 5, 2026 07:02
@devantler devantler added this pull request to the merge queue Jul 5, 2026
Merged via the queue into main with commit ce1a65b Jul 5, 2026
15 checks passed
@devantler devantler deleted the claude/kubescape-c0015-secret-reader-exception branch July 5, 2026 07:27
@github-project-automation github-project-automation Bot moved this from 🏃🏻‍♂️ In Progress to ✅ Done in 🌊 Project Board Jul 5, 2026
@botantler-1

botantler-1 Bot commented Jul 5, 2026

Copy link
Copy Markdown
Contributor

🎉 This PR is included in version 1.101.1 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

@botantler-1 botantler-1 Bot added the released label Jul 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

Status: ✅ Done

Development

Successfully merging this pull request may close these issues.

1 participant