Block insecure Kubernetes manifests with a security SKILL.md
Cursor or Claude Code applies a SKILL.md to k8s manifests and Helm values: privileged containers, hostPath mounts, capability grants, secrets in env, missing resource limits, and NetworkPolicy gaps.
A k8s-security skill in the repo, severity-tagged findings on every manifest PR, and fixes or documented exceptions before pods reach production clusters.
- 1
Test with a deliberately insecure manifest
Create a test PR with privileged: true and a fake secret in env. The skill should block it before you trust it on real manifests.
- 2
Align with cluster admission policies
Copy the same PSS level and capability allowlist your cluster enforces. Agents will approve what the skill does not name in block rules.
- 3
Require severity triage in PR template
Add a manifest security checklist to PR template for paths matching k8s/ or helm/. The skill is useless if reviewers merge without reading findings.
The prompt to paste
Write SKILL.md for reviewing Kubernetes manifests, Helm values, and kustomize overlays before merge. The agent produces merge-blocking security findings, not generic hardening tips. Repository context: [paths to manifests: k8s/, helm/, kustomize/, or .yaml in deploy/] [cluster policy: PSS standard/baseline, allowed service types, namespaces requiring NetworkPolicy] [secret management: sealed-secrets, external-secrets, vault — never plaintext secrets in manifests] [resource quota enforcement: whether limits are required on all workloads] Diff context (paste when using): [PR diff or file list changed] SKILL.md must include: 1. Purpose — catch dangerous pod/workload configs before they reach production clusters where privilege escalation or lateral movement is possible. 2. When to use — any PR touching *.yaml in deploy paths, Helm charts, or kustomize; when not to use — README-only or docs. 3. Severity rubric the agent must use in findings: - Block: privileged: true or allowPrivilegeEscalation, hostPath or hostNetwork without documented exception, secrets in env: (not envFrom secretRef), capabilities: [SYS_ADMIN, NET_ADMIN] without waiver, runAsUser: 0 in prod namespace, public LoadBalancer exposing internal service. - Warn: missing resource limits/requests on workloads, no NetworkPolicy in prod namespace, readOnlyRootFilesystem: false, no securityContext at all, ambient credentials mounted (serviceAccountToken) without explicit use. - Note: deprecated apiVersions, replicas < 2 for prod, missing liveness/readiness probes, antiAffinity not set. 4. Required inputs: file list, target namespace/cluster (dev vs prod), link to cluster policy doc if available. 5. Review steps: - Read each workload spec (Deployment, StatefulSet, DaemonSet, Pod, Job, CronJob) for securityContext at pod and container level. - Flag any privileged: true, hostPath, hostNetwork, hostPID, or hostIPC — demand waiver ticket for each. - Check capabilities: must drop ALL and only add specific caps with justification; block any SYS_* or NET_RAW without named exception. - Scan for secrets in env: — must use envFrom: secretKeyRef or volume mounts; flag plaintext base64 values. - Verify resource limits: memory/cpu limits on all containers; note if missing for prod workloads. - Check NetworkPolicy exists for namespace; if prod and missing, warn egress/ingress is wide open. - List findings as: [Block|Warn|Note] file:line — resource.kind/name — issue — suggested fix (one line). 6. PR comment template: Summary counts by severity, Findings table with resource context, Merge recommendation (block / approve with warnings / approve). 7. Two example prompts: new Deployment yaml vs Helm values granting hostPath to logging sidecar. 8. Pitfalls: approving privileged init containers that still enable breakout, missing resource type like CronJob, allowing capabilities: [NET_BIND_SERVICE] without checking what port it binds, waiving blocks without ticket or review date, ignoring kustomize overlays that override secure base. 9. Done means: every Block resolved or waived with ticket in PR, Warns acknowledged, no secret values printed in comment, deprecated APIs noted for future migration. Rules: - Never print real secret values from manifests; redact to [REDACTED]. - Do not recommend PodSecurityPolicy — it was removed in k8s 1.25; use Pod Security Standards. - Output only SKILL.md markdown.
Init containers run with the same securityContext as app containers unless overridden. The skill must check every container block, not just the first one.
Sample case written by Hidden Logic Lab. Not affiliated with Cursor or Claude Code.
More in Coding
Get new cases in your inbox
Weekly notes on new use cases and agent workflows. No product pitches.