Production engineering guide for pipeline security scanning covering patterns, implementation strategies, and operational best practices.
Pipeline security scanning is the practice of examining CI/CD workflows for vulnerabilities in configuration, dependencies, and execution patterns that could allow unauthorized code execution, data leakage, or privilege escalation. This applies when a pipeline executes untrusted code, handles secrets, or interacts with privileged systems.
Use docker run with specific security scanning image:
docker run --rm \
-v $(pwd):/app \
-v /var/run/docker.sock:/var/run/docker.sock \
registry.example.com/security/scanner:latest \
scan --target /app --format json > scan-results.json
Add to pipeline YAML:
steps:
- name: validate-secrets
image: registry.example.com/tools/secret-validator:latest
commands:
- /validate-secrets.sh
env:
VALIDATE_SECRETS: "true"
Use golangci-lint with security rules:
golangci-lint run --enable=gosec --enable=ineffassign --enable=unused
Execute scanner with explicit registry credentials:
docker scan --token ${DOCKERHUB_TOKEN} my-app:latest
Use npm audit with strict mode:
npm audit --audit-level=high --json > audit-report.json
For Python projects, run:
pip-audit --requirement requirements.txt --output json > pip-audit-report.json
Check that pipeline runs without unnecessary root access:
kubectl get pod -n ci-system $(kubectl get pods -n ci-system -o name | head -1) -o jsonpath='{.spec.containers[0].securityContext.runAsUser}'
Ensure secrets are not exposed in logs or environment variables:
kubectl logs -n ci-system pipeline-runner-12345 | grep -i secret
Examine Kubernetes service account tokens:
apiVersion: v1
kind: ServiceAccount
metadata:
name: pipeline-runner
namespace: ci-system
secrets:
- name: pipeline-runner-token-xyz
Configure audit logging for all pipeline steps:
kubectl apply -f - <<EOF
apiVersion: v1
kind: ConfigMap
metadata:
name: pipeline-audit-config
data:
audit.log: "true"
EOF
Use sha256sum to verify pipeline steps:
sha256sum /usr/local/bin/pipeline-step.sh
Check for unexpected file modifications during pipeline runs:
find /tmp -type f -mmin -5 2>/dev/null
Set up webhook notifications:
webhook:
url: "https://internal.alerts.example.com/pipeline-security"
headers:
Authorization: "Bearer ${ALERT_TOKEN}"
In pipeline configuration:
security:
critical_threshold: 5
high_threshold: 10
medium_threshold: 20
Configure exit codes for security checks:
if [ $(jq -r '.critical.count' scan-results.json) -gt 0 ]; then
exit 1
fi
Secret validation may pass without checking actual values:
# This passes even if no secrets are validated
kubectl exec -it pipeline-runner-12345 -- /validate-secrets.sh || echo "Validation failed"
Scanning may skip important files due to incorrect ignore patterns:
scan:
exclude:
- "*.log"
- "node_modules/**/*"
- "**/test/**/*"
include:
- "src/**/*"
- "config/**/*"
Containers may run with broader permissions than needed:
docker run --user 1000:1000 \
-v /var/run/docker.sock:/var/run/docker.sock \
my-app:latest
Variables may leak into logs or artifacts:
# This leaks secrets to logs
echo "Processing with token: ${SECRET_TOKEN}"
Use multiple scanners in sequence:
docker run --rm -v $(pwd):/app security/scanner1:latest scan --target /app
docker run --rm -v $(pwd):/app security/scanner2:latest scan --target /app
Create local rule definitions:
rules:
- name: "require-secure-registry"
description: "All images must come from secure registry"
condition: "image.registry == 'secure.example.com'"
Use standard HTTP endpoints for pipeline integration:
curl -X POST \
-H "Content-Type: application/json" \
-d '{"status": "failed", "reason": "security-violation"}' \
https://internal.ci.example.com/webhook/pipeline-security
Verify JSON structure:
jq '.results[] | {id, severity, description}' scan-results.json
Validate that all pipeline steps are included:
find . -name "*.sh" -exec basename {} \; | sort > pipeline-steps.txt
Implement manual review process:
# Mark false positives in results
jq '.results[] |= (.false_positive = true) | select(.severity == "HIGH")' scan-results.json
Ensure all required scanners are available:
which golangci-lint || echo "Missing scanner"
Set explicit timeouts in pipeline definitions:
timeout: 300
resources:
limits:
memory: "512Mi"
cpu: "500m"
Use consistent base images:
FROM registry.example.com/base-images/security:latest
COPY . /app
WORKDIR /app
Ensure correct user permissions:
chmod 600 /var/run/docker.sock
chown -R 1000:1000 /tmp
Run validation on each pipeline execution:
# In pipeline script
if [ "${PIPELINE_SECURITY_MODE}" = "strict" ]; then
/validate-security.sh || exit 1
fi
Run security scans only on changed files:
git diff --name-only HEAD~1 HEAD | xargs docker run --rm -v $(pwd):/app security/scanner:latest scan --target
Check for unexpected user switches in pipeline steps:
# In pipeline step
id
whoami
Use kube-bench for Kubernetes security verification:
docker run --rm -v /etc/kubernetes:/etc/kubernetes quay.io/aquasec/kube-bench:latest run --targets master
pipeline:
security:
enabled: true
scanners:
- name: "dependency-check"
image: "registry.example.com/security/dep-scanner:latest"
- name: "container-scan"
image: "registry.example.com/security/container-scanner:latest"
monitoring:
security:
enabled: true
log_level: "debug"
alert_thresholds:
critical: 1
high: 5
medium: 10
report_format: "json"
execution:
security:
run_as_user: 1000
run_as_group: 1000
fs_group: 1000
read_only_root: true
allow_privilege_escalation: false
The most common silent failure occurs when a pipeline validation step passes without actually validating the security configuration, leaving critical vulnerabilities undetected. Always verify that security tools execute and produce output rather than simply exiting with success codes.
This page was rewritten on 15 October 2026. It replaced a templated version that was not specific to its own title. How these pages are written and checked. If anything here is wrong, tell us at [email protected] and we will correct it.
We use cookies for analytics (Google Analytics) and advertising (Google AdSense) to improve your experience and support free content. Privacy Policy