Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
5.6 KiB
ADR-005: Annotation-Based Exemption Management
Status: Accepted Date: 2026-03-05 Deciders: Plugin maintainers
Context
Polaris allows exempting specific workloads from audit checks. When a workload is exempt, Polaris skips all audit checks for that resource. The exemption mechanism uses the annotation polaris.fairwinds.com/exempt=true on the workload resource.
The plugin needs to let users manage these exemptions directly from the Headlamp UI. Several approaches were considered:
- Use Polaris's native annotation-based exemption mechanism
- Create a separate exemption ConfigMap
- Define a custom ExemptionPolicy CRD
- Read-only display with kubectl instructions
Constraints:
- Polaris only recognizes
polaris.fairwinds.com/exemptannotations on workload resources - The plugin is otherwise read-only (this would be the only write operation)
- Users need appropriate RBAC permissions to patch workload resources
- Supported workload types: Deployments, StatefulSets, DaemonSets, Jobs, CronJobs
Requirements:
- Allow users to toggle exemptions for workloads from the Headlamp UI
- Use a mechanism that Polaris actually respects (exemptions must take effect on next scan)
- Support all workload types that Polaris audits
- Respect Kubernetes RBAC (only authorized users can manage exemptions)
Decision
Use Polaris's native annotation-based exemption mechanism. The ExemptionManager component patches polaris.fairwinds.com/exempt annotations onto workload resources via ApiProxy.request.
Implementation:
ExemptionManagercomponent inExemptionManager.tsxprovides a toggle UI for each workload- Exemptions are applied via
ApiProxy.requestwithmethod: 'PATCH'andContent-Type: application/strategic-merge-patch+json - Patch payload sets
metadata.annotations["polaris.fairwinds.com/exempt"]to"true"or removes the annotation - This is the only write operation in the entire plugin
- RBAC is enforced by Kubernetes - users without
patchpermission on the workload resource will receive a 403 error
Consequences
Positive
- ✅ Uses Polaris's own exemption mechanism - No custom storage or translation layer needed
- ✅ Exemptions visible in standard kubectl output -
kubectl get deployment -o yamlshows the annotation - ✅ No additional CRDs or ConfigMaps - No custom resources to manage or clean up
- ✅ Polaris automatically respects annotations - Exemptions take effect on the next audit scan
- ✅ Standard Kubernetes pattern - Annotations are the idiomatic way to attach metadata to resources
Negative
- ❌ Requires write RBAC on workload resources - Users need
patchpermission on deployments, statefulsets, etc.- Mitigated by: RBAC scoping - only users with patch permission can manage exemptions; UI shows clear error for 403
- ❌ Annotation changes not versioned or auditable - Beyond standard Kubernetes resource history
- Mitigated by: Kubernetes audit logging captures annotation patches; resource
metadata.managedFieldstracks changes
- Mitigated by: Kubernetes audit logging captures annotation patches; resource
- ❌ Only supports full-resource exemption - Cannot exempt individual checks (Polaris limitation)
- Mitigated by: This matches Polaris's own annotation-level granularity
Neutral
- Strategic merge patch is the standard Kubernetes patching strategy for adding/removing annotations
- The annotation key (
polaris.fairwinds.com/exempt) is defined by Polaris and unlikely to change - Exemption state is stored on the workload resource itself, so it moves with the resource if migrated
Alternatives Considered
Option 1: Separate Exemption ConfigMap
Pros:
- Centralizes all exemptions in one place
- Does not require write access to workload resources
- Easy to audit all exemptions at once
Cons:
- Polaris does not read exemptions from ConfigMaps - it only checks annotations
- Would require a custom reconciliation controller to sync ConfigMap entries to annotations
- Adds operational complexity
Decision: Rejected (Polaris does not support ConfigMap-based exemptions)
Option 2: Custom ExemptionPolicy CRD
Pros:
- Dedicated resource type for exemption management
- Could support per-check exemptions, time-based exemptions, etc.
- Clean separation of concerns
Cons:
- Over-engineering for what is essentially an annotation toggle
- Would require a custom controller to reconcile CRDs to annotations
- Adds CRD installation as a prerequisite
- Polaris still needs the annotation, so the CRD would be an indirection layer
Decision: Rejected (over-engineering for annotation toggle, would require a controller)
Option 3: Read-Only Display with kubectl Instructions
Pros:
- No write operations in the plugin
- No RBAC requirements beyond read access
- Simpler implementation
Cons:
- Poor user experience - users must switch to terminal to manage exemptions
- Defeats the purpose of a UI plugin
- Error-prone (users may mistype annotation keys)
Decision: Rejected (poor UX compared to in-UI toggle)
References
Revision History
| Date | Author | Change |
|---|---|---|
| 2026-03-05 | Plugin Team | Initial decision |