Security audit skill — analyzes Kubernetes controller/operator code and manifests for vulnerabilities, RBAC over-privilege, CRD injection risks, and cloud-native security anti-patterns. Targets a specific path, feature, or the full project. Produces a severity-ranked report (CRITICAL / WARNING / SUGGESTION).
Perform a security audit of the codebase. Reports findings ranked by severity — never modifies code.
Input: Optionally specify a target after the command:
internal/controller/) — scope to that subtreereconciliation, rbac, crd-validation) — scope to code related to that featureThe audit is organized into seven dimensions. Each dimension is checked against the in-scope code. Skip dimensions that are structurally irrelevant to the target (e.g., skip Webhook Security when no webhooks exist).
+kubebuilder:rbac marker reviewed — no wildcard verbs (*), resources (*), or API groups (*)escalate, bind, or impersonate unless explicitly justifiedlist/watch on Secrets unless required — prefer get on specific namesconfig/rbac/role.yaml matches marker intent (run task dev:manifests and diff)resourceNames used where controller only accesses specific named resourcesnamespace field in resource referencesMinLength, MaxLength, Pattern, Enum, Minimum, Maximumx-kubernetes-validations) enforce semantic constraints the schema cannotoldSelf == self rules on Update+kubebuilder:subresource:status) — prevents spec tampering via status endpointfailurePolicy: Fail (not Ignore)sideEffects: None set correctlyUnsafeDisableDeepCopy is enabled anywhere)ObservedGeneration tracked in status to detect spec/status desynchronizationMaxConcurrentReconciles set appropriately; shared state protected if >1fmt.Errorf("...: %w", err)) but never expose full object specs or secretsget on the resource)r.Recorder.Event(...) — events are namespace-readable)fmt.Sprintf in messages)%v or %+v formatting of K8s objects that may contain secret datalog.Info("...", "object", obj)) — verify production encoder doesn't dump full specrunAsNonRoot: true, explicit runAsUser/runAsGroup)readOnlyRootFilesystem: true)allowPrivilegeEscalation: false)capabilities.drop: ["ALL"])seccompProfile.type: RuntimeDefault)manager.yaml)CGO_ENABLED=0 for static binaryemptyDir with sizeLimitpod-security.kubernetes.io/enforce: restricted)MaxHeaderBytes and request body size limits set on any custom HTTP serversApply when scope is project-wide or covers a significant subsystem.
Trust boundary identification:
Confused deputy assessment:
STRIDE assessment — for each major component or data flow crossing a trust boundary:
| Threat | Question |
|---|---|
| Spoofing | Can an attacker create CRDs that impersonate legitimate resources? Can webhook identity be spoofed? |
| Tampering | Can CRD spec be modified between validation and reconciliation? Can artifacts be tampered between fetch and apply? |
| Repudiation | Are reconciliation actions auditable? Can a user deny creating a CRD that triggered privileged operations? |
| Information Disclosure | Can secrets leak through status, events, logs, or error messages? Can cache contents be exfiltrated? |
| Denial of Service | Can CRD creation trigger unbounded resource consumption? Can reconciliation loops be caused? Can finalizers block namespace deletion? |
| Elevation of Privilege | Can CRD fields reference privileged ServiceAccounts, cross-namespace resources, or cluster-scoped objects to escalate? |
Defense in depth:
Apply the relevant subset based on in-scope code.
crypto/rand used instead of math/rand for any security-relevant values (token generation, nonces)text/template with user-controlled input — use html/template for HTML or strict allowlisting_ for errors from Get, Create, Update, Deletefmt.Sprintf for constructing API paths, label selectors, or field selectors from user inputSetUnstructuredContent — field allowlisting, no arbitrary user mapsclient.IgnoreNotFound(err) used only where NotFound is expected and safe to ignore+kubebuilder:rbac markers accurate: match actual API calls in reconciler+kubebuilder:validation markers on every user-facing CRD field+kubebuilder:default values are safe and don't grant unintended access+kubebuilder:subresource:status present on all CRDs that use status+kubebuilder:printcolumn does not expose sensitive data in kubectl get outputzz_generated.deepcopy.go is current (matches types after task dev:generate)config/manager/manager.yaml security context is restrictive (all 5 hardening fields)config/rbac/role.yaml matches RBAC markers (regenerate and diff)automountServiceAccountToken set appropriatelyfailurePolicy: Failconfig/default/kustomization.yaml enables all security-relevant overlays (RBAC, network policy, metrics auth)CGO_ENABLED=0 for static Go binary.dockerignore excludes .git, .env, credentials, test datagolang:latest)Map the attack surface
Launch an Explore subagent to identify:
Audit each dimension
Launch Explore subagents (parallelize where independent) to check each dimension against the relevant code. Each subagent must return findings with: file path, line number(s), what the issue is, why it matters, and severity (CRITICAL / WARNING / SUGGESTION).
Apply technology-specific checks
Check Go code patterns, Kubebuilder markers, Kustomize manifests, and Dockerfile against the technology-specific checklists.
Deduplicate, rank, and generate report
Identify scope
If a path: use that directory directly. If a feature keyword: launch an Explore subagent to find all code related to that feature (controllers, types, manifests, tests).
Apply relevant dimensions and technology checks
Skip dimensions that don't apply. Apply Dimension 7 (Architecture) only if the target spans a trust boundary.
Generate report
| Severity | Definition | Examples |
|---|---|---|
| CRITICAL | Exploitable vulnerability, privilege escalation, data exfiltration, or auth bypass. Must be addressed before deployment. | Cross-namespace secret exfiltration via CRD field, wildcard RBAC on secrets, hardcoded credentials in source, missing auth on webhook endpoint, confused deputy allowing privilege escalation |
| WARNING | Security weakness with material impact, or best-practice violation that increases attack surface. Should be addressed in the current cycle. | Missing CRD validation markers, RBAC grants broader than needed, secrets in log output, missing network policy, container running as root, image using tags not digests, missing resource limits |
| SUGGESTION | Defense-in-depth improvement, hardening recommendation, or theoretical risk with low current exploitability. Address when convenient. | Missing CEL validation rules, pod security standard labels on namespace, HTTP/2 still enabled, missing seccomp profile, minor RBAC tightening opportunity |
## Security Audit Report
### Scope
- **Target**: Full project | `<path>` | Feature: `<name>`
- **Date**: YYYY-MM-DD
### Summary
| Dimension | Status |
|----------------------------------|---------------------|
| RBAC & Least Privilege | N issues / Clean |
| CRD Security & Validation | N issues / Clean |
| Reconciliation & Controller | N issues / Clean |
| Secret & Sensitive Data | N issues / Clean |
| Container & Pod Security | N issues / Clean |
| Network & TLS Security | N issues / Clean |
| Architecture & Trust Boundaries | N issues / Skipped |
**Totals**: X CRITICAL · Y WARNING · Z SUGGESTION
### CRITICAL (Must fix)
1. **[Title]** — `file/path:line`
**Dimension**: (e.g., CRD Security & Validation)
**Description**: What the issue is and how it could be exploited
**Evidence**: Code snippet or pattern observed
**Recommendation**: Specific fix with file/line target
### WARNING (Should fix)
1. **[Title]** — `file/path:line`
**Dimension**: ...
**Description**: ...
**Evidence**: ...
**Recommendation**: ...
### SUGGESTION (Nice to fix)
1. **[Title]** — `file/path:line`
**Dimension**: ...
**Description**: ...
**Recommendation**: ...
### Positive Observations
- (Security practices done well — always include at least one)
### Skipped / Out of Scope
- (Dimensions or checks skipped and why)
### Final Assessment
- If CRITICAL issues: "X critical issue(s) found. Address before deployment."
- If only warnings: "No critical issues. Y warning(s) to consider."
- If all clear: "All checks passed. No security issues identified in scope."
+kubebuilder:rbac marker at internal/controller/foo_controller.go:42 and replace with get;list;watch" is