Your Kyverno allow lists live in ConfigMaps - who should be able to change them, and how?
answer
- the data is now part of the decision
- edit rights equal policy rights
- not in the namespace it governs
- same repo, same reviewers, same audit
- design the fast lever, do not forbid it
basics
~20 sUpdate rights on that ConfigMap are equivalent to amending the policy, so govern it like policy: platform-owned namespace, the same repository and review as the rule, alerting on writes, and a pre-agreed emergency path that is reconciled back into git.
solid answer
~50 sOnce a rule reads its allow list from a ConfigMap, that ConfigMap is part of the enforcement decision - anyone who can update it can widen the guardrail without touching a policy anyone reviews. So the access control has to match the policy's, not the data's. Keep it in a platform-owned namespace, never in the namespaces it governs, because a team admin's ordinary edit rights there already cover ConfigMaps. Ship it from the same repository and GitOps application as the policy so a change gets the same review and the same audit trail, and the two cannot drift or be pruned apart. Consider guarding it with a Kyverno rule of its own that restricts who may update it and what values are acceptable. Then design the emergency path deliberately: during an incident, editing one ConfigMap is the fastest lever anyone has, so decide in advance who may pull it, that it is alerted on, and that it is reconciled back to git afterwards.
go deeper
Understand that the allow list a rule reads is part of the decision, so changing it changes what is enforced even though no policy file was touched.
Be able to explain why namespace placement matters, given that a namespace's edit role already permits updating ConfigMaps there.
Show the operational package: same repository and deployment as the policy, restricted RBAC, and alerting on writes so an undiscussed change is visible.
Own the tradeoff between review ceremony and operability, and design an explicit emergency path that is loud and reconciled rather than forbidden and used anyway.
## The thing you actually built Moving the allow list out of the policy and into a ConfigMap is good design: the platform team adds a node pool or a zone without editing a rule, and the policy YAML stays stable enough to be reviewed properly. But it also splits the guardrail into two artifacts with two different access-control stories, and only one of them looks like security to the people around it. The question to ask out loud: **who can add a value to that list, and what review does that change get?** If the honest answer is "anyone with edit in that namespace, and no review", then the policy's change-control is theatre - the interesting change is one `kubectl edit` away. ## Where it lives The first decision is placement. Do not put the ConfigMap in the namespaces the policy governs. Kubernetes' built-in edit role covers ConfigMaps, so every namespace admin you granted normal self-service to can already rewrite their own guardrail's inputs. Put it in a namespace the platform team owns, where team RBAC does not reach, and reference it by namespace from the rule. ## How it changes The second decision is the change path. Ship the ConfigMap from the same repository and the same GitOps application as the policy that reads it. That buys four things at once: the same reviewers, an audit trail that is a commit history rather than an API server log you have to go looking for, atomic deployment so the policy and its data cannot be created in the wrong order, and pruning that removes both together instead of orphaning one. CODEOWNERS on the file is what turns "same repo" into "same review". A widening of the allow list should require the same approver a widening of the rule would. ## Guarding the guardrail Where the list is genuinely sensitive, you can point policy at it: a Kyverno rule matching updates to that ConfigMap in that namespace, restricted by the requesting subject, that refuses writes from anyone but the platform's automation - and optionally asserts something about the values themselves, so a fat-fingered wildcard cannot be introduced. This is worth doing when the list is short and high-stakes, and not worth the recursion when it is long and routine. Be honest about the recursion in the interview: the policy engine cannot be its own root of trust, and the real backstop is that changes are visible, attributable and alerted on. ## Detection is part of the design Whichever route you take, alert on writes. A change to the list should show up somewhere a human sees it - a chat notification off the audit log or off the GitOps diff - because the failure mode you care about is not a malicious edit but an undiscussed one. "Someone added `*` to unblock a release on Friday" is an ordinary story, and the only thing that makes it survivable is that Monday's reader can see it happened. ## The emergency lever Now the part that separates a policy that survives contact with a team from one that gets disabled wholesale. The ConfigMap is the fastest safe lever in the system: during an incident, adding one value unblocks a deployment in seconds without editing, testing or rolling out a policy. That is a feature, and you should design it rather than pretend it will not be used. A workable shape: - Name in advance the small group who may make a direct edit, and say plainly that they may. - Require that the edit is announced where the incident is being run, so it is on the timeline. - Alert on it automatically, so a direct edit is never silent even if the announcement is forgotten. - Require a reconciling pull request within a fixed window, so git converges back to reality and the next GitOps sync does not silently revert - or silently keep - the change depending on how your tooling handles drift. - Review it afterwards: was the value permanent or should it come back out? ## What good judgment sounds like A strong answer resists two easy extremes. "Lock it down so only a change-advisory board can edit it" recreates the ceremony the indirection existed to avoid, and teams route around it. "It is just a ConfigMap" ignores that it is now a decision input for every workload in the cluster. The defensible middle is: policy-grade access control and review on the normal path, an explicit and fast emergency path that is loud rather than forbidden, and monitoring that makes both visible. The indirection is what makes the guardrail operable at all - the answer is to govern it, not to remove it.
- Why is putting that ConfigMap in the team's own namespace a problem?The built-in edit role for a namespace already covers ConfigMaps, so every team admin you granted normal self-service to can rewrite the list their own workloads are judged against. The policy would still be enforced faithfully - against data the governed party controls. Keep it in a platform-owned namespace the rule references by namespace.
- Would you use a policy to protect the ConfigMap the policy reads?Sometimes. A rule restricting updates to that object by subject, and asserting the values look sane, is cheap and worth it for a short, high-stakes list. But be clear that the engine cannot be its own root of trust - if someone can change policies they can change this too. The durable controls are attribution, alerting and review, with the policy as a speed bump against accidents.
- How do you keep an emergency edit from quietly becoming permanent?Alert on any direct write, require a reconciling pull request inside a fixed window, and let the GitOps sync be the thing that converges state. Then review the value at the incident retro and decide whether it stays. The failure to avoid is a list that accretes exceptions nobody remembers requesting, which is how an allow list turns into a wildcard over a year.
saying these in an interview costs you the question
- Treats the ConfigMap as ordinary config, not policy input
- Places the allow list in the namespace it governs
- Locks it down so hard teams bypass the policy entirely
- Has no announced path for an urgent change
- Never alerts on direct writes to the list