Skill Being Reviewed
Skill name: container-security
Skill path: skills/cloud/container-security/
False Positive Analysis
Benign code that triggers a false positive:
apiVersion: apps/v1
kind: Deployment
metadata:
name: app
spec:
template:
spec:
securityContext:
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault
initContainers:
- name: volume-permissions
image: busybox:1.36@sha256:4be8f0d59d41a3a494f1c350f064a9f1c8b3b7595510e164e47f2c6d3fda25a2
command: ["sh", "-c", "chown -R 65532:65532 /work"]
securityContext:
runAsUser: 0
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop: ["ALL"]
volumeMounts:
- name: work
mountPath: /work
containers:
- name: app
image: ghcr.io/example/app@sha256:1111111111111111111111111111111111111111111111111111111111111111
securityContext:
runAsUser: 65532
runAsGroup: 65532
runAsNonRoot: true
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop: ["ALL"]
volumes:
- name: work
emptyDir: {}
Why this is a false positive:
The skill's severity table uses "running as root" as a high-severity example and the common pitfalls correctly note that init containers must be reviewed. However, not every root-running init container has the same risk as a root application container. A short-lived init container that only changes ownership on an emptyDir, drops all capabilities, denies privilege escalation, uses RuntimeDefault seccomp, has no hostPath, and is digest-pinned is still a policy exception, but it should be scored differently from a long-running root workload with host mounts or broad capabilities. The report should require reviewers to capture container type, duration, mounts, capabilities, and compensating controls before assigning severity.
Coverage Gaps
Missed variant 1: RuntimeClass / sandboxed runtime evidence is not collected
apiVersion: apps/v1
kind: Deployment
metadata:
name: untrusted-plugin-runner
spec:
template:
spec:
runtimeClassName: gvisor
containers:
- name: runner
image: ghcr.io/example/plugin-runner@sha256:2222222222222222222222222222222222222222222222222222222222222222
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop: ["ALL"]
Why it should be caught:
For multi-tenant runners, plugin execution, CI workloads, or untrusted document/media processing, the isolation boundary may depend on RuntimeClass choices such as gVisor, Kata Containers, or another sandboxed runtime. The current skill checks ordinary Pod Security controls but does not ask reviewers to identify whether high-risk workloads use the default runtime versus a sandboxed runtime, nor whether the referenced RuntimeClass object exists and is approved for that namespace.
Missed variant 2: Admission controls may mutate or validate security context after manifests are reviewed
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: require-runtime-default-seccomp
spec:
validationFailureAction: Enforce
rules:
- name: require-runtime-default
match:
any:
- resources:
kinds: ["Pod"]
validate:
pattern:
spec:
securityContext:
seccompProfile:
type: RuntimeDefault
Why it should be caught:
The skill mentions OPA/Gatekeeper in the use cases, but the main process and report template do not require evidence from Kyverno, Gatekeeper, or Kubernetes ValidatingAdmissionPolicy/MutatingAdmissionPolicy resources. That can create both false negatives (a manifest looks unsafe but is blocked/mutated before admission) and false positives (a manifest looks safe but the policy is only Audit, excludes the namespace, or has a broad exception). Reviewers should record policy engine, mode (Enforce vs Audit/dry-run), namespace selectors, exception resources, and whether policies cover init and ephemeral containers.
Edge Cases
- A
runtimeClassName string in a Pod is not enough evidence by itself; the review should check for a matching RuntimeClass object and, when possible, the handler/runtime implementation used by the cluster.
- Admission policies often have namespace or service-account exceptions. A policy existing in the repo should not be counted as protection unless the workload under review is actually selected by it.
- Kubernetes' newer CEL-based admission policies can enforce controls without Gatekeeper/Kyverno CRDs, so discovery should include
ValidatingAdmissionPolicy, ValidatingAdmissionPolicyBinding, MutatingAdmissionPolicy, and MutatingAdmissionPolicyBinding manifests.
- Root init containers should be treated as scoped exceptions requiring justification and compensating controls, not automatically bucketed with privileged long-running application containers.
Remediation Quality
Comparison to Other Tools
| Tool |
Catches this? |
Notes |
| Semgrep |
Partial |
Semgrep can flag Kubernetes fields such as privileged containers or missing runAsNonRoot, but repository-local rules usually cannot prove whether a RuntimeClass exists in-cluster or whether admission policies are enforced for a namespace. |
| CodeQL |
No |
CodeQL is not typically used for Kubernetes admission-policy reachability or runtime-class validation. |
| Other: Kyverno / Gatekeeper / Kubernetes admission |
Partial |
These tools can enforce the desired controls at admission time, but a source review still needs to verify policy mode, selectors, exceptions, and workload coverage. |
Overall Assessment
Strengths:
- Clear mapping to CIS Docker, CIS Kubernetes, NIST SP 800-190, and Pod Security Standards.
- Good coverage of common high-impact misconfigurations: privileged pods, host namespaces, missing network policies, wildcard RBAC, writable root filesystems, and plaintext secrets.
- Useful practical pitfalls around init/sidecar coverage, Helm values, default namespaces, and BuildKit-compatible remediation.
Needs improvement:
- Runtime isolation (
runtimeClassName, gVisor/Kata/default runtime) is not part of the context checklist or output format.
- Admission policy evidence is mentioned generally but not collected systematically, so reviewers can miss enforcement modes, selectors, and exceptions.
- Severity guidance does not distinguish tightly scoped root init containers from long-running root application containers with broader privileges.
Priority recommendations:
- Add
RuntimeClass and runtimeClassName discovery to Step 1, plus a report field showing default/sandboxed runtime per high-risk workload.
- Add an admission-control evidence section covering Kyverno, Gatekeeper, and Kubernetes CEL admission policy resources, including mode, selectors, and exceptions.
- Refine severity examples so root init containers with dropped capabilities/no hostPath/no privilege escalation are treated as justified exceptions or medium-risk hardening gaps unless additional escape paths are present.
Bounty Info
Skill Being Reviewed
Skill name:
container-securitySkill path:
skills/cloud/container-security/False Positive Analysis
Benign code that triggers a false positive:
Why this is a false positive:
The skill's severity table uses "running as root" as a high-severity example and the common pitfalls correctly note that init containers must be reviewed. However, not every root-running init container has the same risk as a root application container. A short-lived init container that only changes ownership on an
emptyDir, drops all capabilities, denies privilege escalation, uses RuntimeDefault seccomp, has no hostPath, and is digest-pinned is still a policy exception, but it should be scored differently from a long-running root workload with host mounts or broad capabilities. The report should require reviewers to capture container type, duration, mounts, capabilities, and compensating controls before assigning severity.Coverage Gaps
Missed variant 1: RuntimeClass / sandboxed runtime evidence is not collected
Why it should be caught:
For multi-tenant runners, plugin execution, CI workloads, or untrusted document/media processing, the isolation boundary may depend on
RuntimeClasschoices such as gVisor, Kata Containers, or another sandboxed runtime. The current skill checks ordinary Pod Security controls but does not ask reviewers to identify whether high-risk workloads use the default runtime versus a sandboxed runtime, nor whether the referencedRuntimeClassobject exists and is approved for that namespace.Missed variant 2: Admission controls may mutate or validate security context after manifests are reviewed
Why it should be caught:
The skill mentions OPA/Gatekeeper in the use cases, but the main process and report template do not require evidence from Kyverno, Gatekeeper, or Kubernetes
ValidatingAdmissionPolicy/MutatingAdmissionPolicyresources. That can create both false negatives (a manifest looks unsafe but is blocked/mutated before admission) and false positives (a manifest looks safe but the policy is onlyAudit, excludes the namespace, or has a broad exception). Reviewers should record policy engine, mode (EnforcevsAudit/dry-run), namespace selectors, exception resources, and whether policies cover init and ephemeral containers.Edge Cases
runtimeClassNamestring in a Pod is not enough evidence by itself; the review should check for a matchingRuntimeClassobject and, when possible, the handler/runtime implementation used by the cluster.ValidatingAdmissionPolicy,ValidatingAdmissionPolicyBinding,MutatingAdmissionPolicy, andMutatingAdmissionPolicyBindingmanifests.Remediation Quality
Comparison to Other Tools
runAsNonRoot, but repository-local rules usually cannot prove whether aRuntimeClassexists in-cluster or whether admission policies are enforced for a namespace.Overall Assessment
Strengths:
Needs improvement:
runtimeClassName, gVisor/Kata/default runtime) is not part of the context checklist or output format.Priority recommendations:
RuntimeClassandruntimeClassNamediscovery to Step 1, plus a report field showing default/sandboxed runtime per high-risk workload.Bounty Info