Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@ spec:
posture:
- controlID: C-0053
action: ignore
- controlID: C-0015
action: ignore
- controlID: C-0007
action: ignore
- controlID: C-0037
Expand All @@ -35,14 +33,19 @@ spec:
action: ignore
- controlID: C-0035
action: ignore
# NOTE: RBAC-review controls are NOT suppressible here. Kubescape anchors
# NOTE: RBAC-object controls are NOT suppressible here. Kubescape anchors
# their findings on the RBAC Role/ClusterRole/binding object, not on a
# namespaced workload, so a namespaceSelector match never applies (proven:
# the namespaced velero-server binding kept failing despite `velero` being
# the namespaced velero-server Role kept failing despite `velero` being
# listed below). They are handled by explicit kind+name `match.resources` CRs:
# - C-0187 (wildcard RBAC, CIS-5.1.3) β†’ wildcard-rbac.yaml
# - C-0002 (exec into container) β†’ exec-into-container-rbac.yaml
# Headlamp is fixed at the root (SA scoped to read-only cluster-reader).
# - C-0187 (wildcard RBAC, CIS-5.1.3) -> wildcard-rbac.yaml
# - C-0015 (list Kubernetes secrets) -> secret-reader-rbac.yaml
# - C-0002 (exec into container) -> exec-into-container-rbac.yaml
# Headlamp is fixed at the root (SA scoped to read-only cluster-reader); Flux
# and Velero are exempted by-design in wildcard-rbac.yaml.
# The other RBAC controls still listed here (C-0053, C-0007, C-0037, C-0031,
# C-0063, C-0035, C-0188) have the same namespaceSelector limitation and
# should migrate to kind+name matching too - tracked separately.
- controlID: C-0188
action: ignore
match:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ resources:
- kubescape-privileged.yaml
- pod-security-mutations.yaml
- readonly-rootfs-pending.yaml
- secret-reader-rbac.yaml
- service-account-tokens.yaml
- talos-cis-control-plane-false-positives.yaml
- talos-cis-worker-false-positives.yaml
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,269 @@
---
# Secret-reader RBAC exception (Kubescape C-0015, "List Kubernetes secrets") for
# the controllers, operators and databases that legitimately read Secrets BY
# DESIGN.
#
# Why this is a separate CR and not a `namespaceSelector` entry in
# controller-rbac.yaml: a namespaceSelector does NOT suppress C-0015. Like
# C-0187 (see wildcard-rbac.yaml), C-0015 is an RBAC control β€” Kubescape attaches
# the finding to the RBAC object graph (the ServiceAccount subject plus its
# Role/ClusterRole and RoleBinding/ClusterRoleBinding), not to a namespaced
# workload. The kubescape CRD exceptions getter turns a namespaceSelector into a
# bare `{namespace: X}` designator, and the suppressible objects here are almost
# all cluster-scoped (a ClusterRole/ClusterRoleBinding has no namespace), so the
# namespace never matches and the exception is inert. Proven live: origin-ca-issuer
# is in controller-rbac.yaml's selected `cert-manager` namespace yet still fails
# C-0015. Matching the specific RBAC objects by kind+name is the mechanism that
# actually works (opa-utils exceptionprocessor.go re-wraps each related object and
# compares its top-level kind+name) β€” the same pattern wildcard-rbac.yaml uses.
#
# Match the permission-bearer (the Role/ClusterRole that grants the secrets verb),
# and β€” for the cluster-admin holders whose secret access comes from the shared
# `cluster-admin` ClusterRole β€” the specific ClusterRoleBinding (as wildcard-rbac.yaml
# does), so a NEW cluster-admin binding still trips C-0015.
#
# Deliberately NOT exempted (kept flagged so the control keeps doing its job):
# - The unused tenant SAs `wedding-app` and `ascoachingogvaner`, bound to the
# broad built-in `ClusterRole/edit`: their pods run as the `default` SA, so
# these edit-bound SAs are dormant namespace-wide secret grants = genuine
# over-privilege to remove, not to silence.
# - `crossview-sa` (`crossview-role` grants `*/* get,list,watch`, i.e. reads all
# Secret contents for a topology viewer) β€” tighten upstream in the crossview
# chart, don't exempt.
# - The break-glass admin groups `system:masters` (cluster-admin) and
# `crossplane:masters` (crossplane-admin): surfacing the highest-privilege
# identities is the control working as intended.
# - `longhorn-support-bundle` (an on-demand diagnostic SA bound to cluster-admin)
# β€” same treatment as in wildcard-rbac.yaml.
#
# Keep this list and the Headlamp mirror
# (controllers/kubescape/config-map-headlamp-exceptions.yaml) in sync by hand.
apiVersion: kubescape.io/v1beta1
kind: ClusterSecurityException
metadata:
name: secret-reader-rbac
spec:
reason: >-
Controllers, operators and databases that read Kubernetes Secrets by design
(cert-manager, External Secrets, CloudNativePG + Barman backups, Crossplane
and its providers, Kyverno, Flux/tofu, KEDA, Longhorn, Cilium, the Kubescape
operator, the built-in kube-controller-manager controllers, and the tenant
databases). Matched by the specific RBAC object (Role/ClusterRole, or the
binding for cluster-admin holders) so a new/accidental secret-reader
elsewhere still trips C-0015. Over-privileged or admin identities
(unused tenant `edit` SAs, crossview's wildcard read, the cluster-admin /
crossplane admin groups) are intentionally left flagged.
posture:
- controlID: C-0015
action: ignore
match:
resources:
# Flux GitOps & tofu-controller
- apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: ^crd-controller-flux-system$
- apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: ^tf-runner-role$
- apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: ^tofu-cluster-reconciler-role$
- apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: ^tofu-manager-role$
# Cluster-admin holders (Flux reconcilers, Velero) β€” matched by binding, mirroring wildcard-rbac.yaml
- apiGroup: rbac.authorization.k8s.io
kind: ClusterRoleBinding
name: ^cluster-reconciler-flux-system$
- apiGroup: rbac.authorization.k8s.io
kind: ClusterRoleBinding
name: ^flux-operator$
- apiGroup: rbac.authorization.k8s.io
kind: ClusterRoleBinding
name: ^velero-server$
# cert-manager (TLS/CA secret management)
- apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: ^cert-manager-cainjector$
- apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: ^cert-manager-controller-certificates$
- apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: ^cert-manager-controller-challenges$
- apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: ^cert-manager-controller-clusterissuers$
- apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: ^cert-manager-controller-issuers$
- apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: ^cert-manager-controller-orders$
- apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: ^origin-ca-issuer-controller$
- apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: ^simply-dns-webhook:secret-access$
- apiGroup: rbac.authorization.k8s.io
kind: Role
name: ^cert-manager-webhook:dynamic-serving$
- apiGroup: rbac.authorization.k8s.io
kind: Role
name: ^trust-manager$
# CloudNativePG operator + tenant databases & Barman backups
- apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: ^cloudnative-pg$
- apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: ^plugin-barman-cloud$
- apiGroup: rbac.authorization.k8s.io
kind: Role
name: ^backstage-db$
- apiGroup: rbac.authorization.k8s.io
kind: Role
name: ^coroot-db$
- apiGroup: rbac.authorization.k8s.io
kind: Role
name: ^coroot-db-barman-cloud$
- apiGroup: rbac.authorization.k8s.io
kind: Role
name: ^umami-db$
- apiGroup: rbac.authorization.k8s.io
kind: Role
name: ^umami-db-barman-cloud$
- apiGroup: rbac.authorization.k8s.io
kind: Role
name: ^wedding-db$
- apiGroup: rbac.authorization.k8s.io
kind: Role
name: ^wedding-db-barman-cloud$
# External Secrets Operator
- apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: ^external-secrets-cert-controller$
- apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: ^external-secrets-controller$
# Crossplane + upjet providers (reconcile provider-credential Secrets)
- apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: ^crossplane$
- apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: ^crossplane:provider:provider-aws-iam-[0-9a-f]+:system$
- apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: ^crossplane:provider:provider-family-aws-[0-9a-f]+:system$
- apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: ^crossplane:provider:provider-upjet-github-[0-9a-f]+:system$
- apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: ^crossplane:provider:provider-upjet-unifi-[0-9a-f]+:system$
# Kyverno policy engine
- apiGroup: rbac.authorization.k8s.io
kind: Role
name: ^kyverno:admission-controller$
- apiGroup: rbac.authorization.k8s.io
kind: Role
name: ^kyverno:background-controller$
- apiGroup: rbac.authorization.k8s.io
kind: Role
name: ^kyverno:cleanup-controller$
- apiGroup: rbac.authorization.k8s.io
kind: Role
name: ^kyverno:reports-controller$
# Observability & monitoring
- apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: ^coroot-cluster-agent$
- apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: ^coroot-operator$
- apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: ^kube-prometheus-stack-grafana-clusterrole$
- apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: ^kube-prometheus-stack-kube-state-metrics$
- apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: ^kube-prometheus-stack-operator$
# Storage (Longhorn, Hetzner CSI)
- apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: ^hcloud-csi-controller$
- apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: ^longhorn-role$
- apiGroup: rbac.authorization.k8s.io
kind: Role
name: ^longhorn$
# Cilium CNI & Gateway (TLS secrets)
- apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: ^cilium-operator$
- apiGroup: rbac.authorization.k8s.io
kind: Role
name: ^cilium-gateway-secrets$
- apiGroup: rbac.authorization.k8s.io
kind: Role
name: ^cilium-tlsinterception-secrets$
- apiGroup: rbac.authorization.k8s.io
kind: Role
name: ^hubble-generate-certs$
# KEDA autoscaler
- apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: ^keda-operator$
- apiGroup: rbac.authorization.k8s.io
kind: Role
name: ^keda-operator-certs$
# Kubernetes control-plane (kube-controller-manager) built-in controllers
- apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: ^system:controller:generic-garbage-collector$
- apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: ^system:controller:namespace-controller$
- apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: ^system:controller:resourcequota-controller$
- apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: ^system:kube-controller-manager$
- apiGroup: rbac.authorization.k8s.io
kind: Role
name: ^system:controller:bootstrap-signer$
- apiGroup: rbac.authorization.k8s.io
kind: Role
name: ^system:controller:token-cleaner$
# Kubescape operator/scanner
- apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: ^kubescape$
- apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: ^operator$
- apiGroup: rbac.authorization.k8s.io
kind: Role
name: ^operator$
Comment thread
coderabbitai[bot] marked this conversation as resolved.
# Other platform controllers (flagger, reloader, ksail-operator, OpenBao)
- apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: ^flagger$
- apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: ^ksail-operator$
- apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: ^reloader-reloader-role$
- apiGroup: rbac.authorization.k8s.io
kind: Role
name: ^vault-config$
- apiGroup: rbac.authorization.k8s.io
kind: Role
name: ^velero-server$
Loading