Skip to content

Tighten metadata Role RBAC: drop unused ConfigMap list/watch, restrict get/update to reloader-meta-info #1221

Open

Description

@rasheedamir

Summary

The always-created metadata Role (<release>-metadata-role) grants broader ConfigMap permissions than the code actually uses. Two of the five verbs appear unused, and the used ones can be scoped to the single ConfigMap Reloader writes — the same resourceNames pattern the role already applies to the HA leader-election Lease.

This came out of a security/least-privilege review of the chart for an enterprise third-party risk assessment; tightening it lets Reloader make a stronger claim in regulated environments ("no broad ConfigMap write access anywhere, including its own namespace").

Current state

deployments/kubernetes/chart/reloader/templates/role.yaml (chart v2.2.17) always creates, when rbac.enabled: true:

- apiGroups: [""]
  resources: ["configmaps"]
  verbs: ["list", "get", "watch", "create", "update"]

What the code actually does

The only production write path for ConfigMaps in Reloader's own namespace is the meta-info feature:

  • pkg/common/common.go → PublishMetaInfoConfigmap() — called once at startup from internal/pkg/cmd/reloader.go
  • It does Get → Update (if exists) or Create on a fixed-name ConfigMap: reloader-meta-info (pkg/common/metainfo.go, MetaInfoConfigmapName)
  • The ConfigMap contains build info, command-line options, and deployment info — operational metadata only

Grepping all non-test Go code, there are no List or Watch calls on ConfigMaps in the deployment namespace via this Role (cluster/namespace watch-scope reads are covered by the separate ClusterRole/Role read-only rules). Leader election uses LeaseLock exclusively (internal/pkg/leadership/leadership.go), not ConfigMap locks.

Proposal

Drop the unused verbs and restrict get/update by resourceNames, mirroring the existing lease-lock pattern in the same file:

- apiGroups: [""]
  resources: ["configmaps"]
  verbs: ["create"]          # create cannot be resourceNames-restricted in Kubernetes RBAC

- apiGroups: [""]
  resources: ["configmaps"]
  resourceNames: ["reloader-meta-info"]
  verbs: ["get", "update"]

Benefits

  • Least privilege: Reloader's ServiceAccount can no longer read or enumerate arbitrary ConfigMaps in its own namespace (which may include Helm release ConfigMaps and other operators' state), nor update anything except reloader-meta-info
  • Consistency: the same role already restricts the HA Lease to resourceNames: ["stakater-reloader-lock"]
  • Security posture: enables an unqualified "watched ConfigMap/Secret access is read-only; writes are limited to two fixed-name objects in its own namespace" statement for enterprise/TPRM reviews

Caveats to verify

  • Anything external (e.g. enterprise console/tooling) that reads reloader-meta-info uses its own credentials, so it should be unaffected — worth confirming
  • If a future feature needs list/watch in the deployment namespace, it can be added back with a targeted rule

Happy to send a PR if the approach is agreed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions