## Summary - Add `compensating-controls.yaml` tracking 9 named controls that justify suppressed security findings - Update all Prowler mutelist descriptions with `CC: <id>` references to named controls - Add `mise run review-compensating-controls` task — surfaces stalest control with all codebase references - Add [[review-compensating-controls]] how-to doc - Organize Prowler and Kingfisher reports into `YYYY-MM-DD` subdirectories ### Compensating controls | ID | Mitigates | |----|-----------| | `single-user-cluster` | Image cache abuse, RBAC breadth, system pod privileges | | `tailscale-network-isolation` | Profiling endpoints, weak TLS, debug ports | | `local-registry` | AlwaysPullImages gap | | `sso-gated-admin-tools` | ArgoCD wildcard RBAC | | `operator-managed-pods` | Tailscale proxy pod security settings | | `ephemeral-privileged-jobs` | Prowler hostPID exposure | | `trusted-ci-only` | Forgejo runner DinD | | `init-container-isolation` | Grafana root init container | | `observability-stack-audit` | Missing apiserver audit logging | ## Test plan - [ ] `mise run review-compensating-controls` shows table and references - [ ] `kubectl kustomize argocd/manifests/prowler/` renders correctly - [ ] Sync prowler and kingfisher, verify next scan writes to dated subdirectory - [ ] Grep for `CC:` in mutelist files — every muted finding should have at least one 🤖 Generated with [Claude Code](https://claude.com/claude-code) Reviewed-on: #320
3.2 KiB
| title | modified | last-reviewed | tags | |||
|---|---|---|---|---|---|---|
| Review Compensating Controls | 2026-03-30 | 2026-03-30 |
|
Review Compensating Controls
How to periodically review compensating controls that justify suppressed security findings.
Review by Staleness
Show controls sorted by when they were last reviewed (most stale first):
mise run review-compensating-controls
This reads compensating-controls.yaml (repo root), sorts by last-reviewed, and displays the most stale control with all codebase references. It also searches for every file that references the control ID, so you can see exactly which suppressed findings depend on it.
To show more entries:
mise run review-compensating-controls --limit 20
What is a Compensating Control?
A compensating control is a security measure that mitigates the risk a finding was designed to detect, when the finding itself cannot be directly remediated. For example:
- Finding: API server does not enable AlwaysPullImages admission plugin
- Risk: Untrusted users could run pods using cached images they shouldn't have access to
- Compensating control:
single-user-cluster— only the operator has kubectl access; no untrusted users can create pods
Controls are documented in compensating-controls.yaml and referenced from security tool configurations (Prowler mutelist files, Kingfisher config, etc.) using the format CC: <control-id>.
Review Process
For each control up for review:
-
Understand the risk. Read each suppressed finding that references this control. What attack or misconfiguration does the original check guard against?
-
Verify the control is in effect. Follow the verification steps in the control's
notesfield. For example, fortailscale-network-isolation, check that the cluster is not directly internet-exposed and Tailscale ACLs are enforced. -
Assess whether the control actually mitigates the risk. A compensating control should address the same threat the check was designed to catch, not just be a vaguely related security measure. If it doesn't hold up, either:
- Fix the underlying finding and remove the suppression
- Document a stronger or more specific compensating control
-
Check for changed circumstances. Has the cluster gained new users? Has a service been exposed publicly? Has an operator added native support for the missing feature? Any of these could invalidate the control.
-
Update the review date. Edit
compensating-controls.yamland setlast-reviewedto today's date. Commit alongside any changes.
Adding a New Control
When suppressing a new security finding, either map it to an existing control or add a new one:
- id: my-new-control
description: >-
What this control does and how it mitigates the specific risk.
created: 2026-03-30
last-reviewed: 2026-03-30
notes: >-
How to verify this control is still in effect.
Then reference it in the suppression configuration with CC: my-new-control.
Related
- security — Security posture overview
- read-compliance-reports — Accessing and interpreting Prowler reports
- review-services — Periodic service version review (similar staleness pattern)