Perform security risk analysis on Kubernetes resource manifests using Kubesec to identify misconfigurations, privilege escalation risks, and deviations from security best practices.
Perform security risk analysis on Kubernetes resource manifests using Kubesec to identify misconfigurations, privilege escalation risks, and deviations from security best practices.
Kubesec is an open-source security risk analysis tool developed by ControlPlane that inspects Kubernetes resource manifests for common exploitable risks such as privilege escalation, writable host mounts, and excessive capabilities. It assigns a numerical security score to each resource and provides actionable recommendations for hardening. Kubesec can be used as a CLI binary, Docker container, kubectl plugin, admission webhook, or REST API endpoint.
When to Use
When conducting security assessments that involve scanning kubernetes manifests with kubesec
When following incident response procedures for related security events
When performing scheduled security testing or auditing activities
When validating security controls through hands-on testing
Prerequisites
Kubernetes manifest files (YAML/JSON) for Deployments, Pods, DaemonSets, StatefulSets
Docker or Go runtime for local installation
kubectl access for scanning live cluster resources
CI/CD pipeline access for automated scanning integration
Core Concepts
Security Scoring System
Kubesec assigns a score to each Kubernetes resource based on security checks:
Positive scores: Awarded for security-enhancing configurations (readOnlyRootFilesystem, runAsNonRoot)
Zero or negative scores: Indicate missing security controls or dangerous configurations
Critical advisories: Flagged configurations that represent immediate security risks
# Linux/macOS
curl -sSL https://github.com/controlplaneio/kubesec/releases/latest/download/kubesec_linux_amd64.tar.gz | \
tar xz -C /usr/local/bin/ kubesec
# Verify installation
kubesec version
Docker Installation
docker pull kubesec/kubesec:v2
# Scan a manifest file
docker run -i kubesec/kubesec:v2 scan /dev/stdin < deployment.yaml
kubectl Plugin
kubectl krew install kubesec-scan
kubectl kubesec-scan pod mypod -n default
Practical Scanning
Scanning a Single Manifest
# Scan a deployment manifest
kubesec scan deployment.yaml
# Scan with JSON output
kubesec scan -o json deployment.yaml
# Scan from stdincat pod.yaml | kubesec scan -
Sample Output
[{"object":"Pod/web-app.default","valid":true,"fileName":"pod.yaml","message":"Passed with a score of 3 points","score":3,"scoring":{"passed":[{"id":"ReadOnlyRootFilesystem","selector":"containers[] .securityContext .readOnlyRootFilesystem == true","reason":"An immutable root filesystem prevents applications from writing to their local disk","points":1},{"id":"RunAsNonRoot","selector":"containers[] .securityContext .runAsNonRoot == true","reason":"Force the running image to run as a non-root user","points":1},{"id":"LimitsCPU","selector":"containers[] .resources .limits .cpu","reason":"Enforcing CPU limits prevents DOS via resource exhaustion","points":1}],"advise":[{"id":"ApparmorAny","selector":"metadata .annotations .\"container.apparmor.security.beta.kubernetes.io/nginx\"","reason":"Well defined AppArmor policies reduce the attack surface of the container","points":3},{"id":"ServiceAccountName","selector":".spec .serviceAccountName","reason":"Service accounts restrict Kubernetes API access and should be configured","points":3}]}}]
Scanning Multiple Resources
# Scan all YAML files in a directoryfor file in manifests/*.yaml; doecho"=== Scanning $file ==="
kubesec scan "$file"done# Scan multi-document YAML
kubesec scan multi-resource.yaml
Using the HTTP API
# Scan via the public API
curl -sSX POST --data-binary @deployment.yaml \
https://v2.kubesec.io/scan
# Run a local API server
kubesec http --port 8080 &
# Scan against local server
curl -sSX POST --data-binary @deployment.yaml \
http://localhost:8080/scan
CI/CD Integration
GitHub Actions
name:KubesecScanon: [pull_request]
jobs:kubesec:runs-on:ubuntu-lateststeps:-uses:actions/checkout@v4-name:InstallKubesecrun:|
curl -sSL https://github.com/controlplaneio/kubesec/releases/latest/download/kubesec_linux_amd64.tar.gz | \
tar xz -C /usr/local/bin/ kubesec
-name:ScanManifestsrun:|
FAIL=0
for file in k8s/*.yaml; do
SCORE=$(kubesec scan "$file" | jq '.[0].score')
echo "$file: score=$SCORE"
if [ "$SCORE" -lt 0 ]; then
echo "FAIL: $file has critical issues (score: $SCORE)"
FAIL=1
fi
done
exit $FAIL
GitLab CI
kubesec-scan:stage:securityimage:kubesec/kubesec:v2script:-|
for file in k8s/*.yaml; do
kubesec scan "$file" > /tmp/result.json
SCORE=$(cat /tmp/result.json | jq '.[0].score')
if [ "$SCORE" -lt 0 ]; then
echo "CRITICAL: $file scored $SCORE"
cat /tmp/result.json | jq '.[0].scoring.critical'
exit 1
fi
done
artifacts:paths:-kubesec-results/
Admission Webhook
Deploy Kubesec as a ValidatingWebhookConfiguration to reject insecure manifests at deploy time: