#1221·Reloader

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

Author: rasheedamirCreated Sep 17, 2026Updated Sep 17, 2026
Labelskind/enhancement

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:

yaml
- 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.goPublishMetaInfoConfigmap() — called once at startup from internal/pkg/cmd/reloader.go
  • It does GetUpdate (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:

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