Detecting Compromised CLI Tools in Ci/cd Pipelines
Practical steps to detect and mitigate compromised CLI tools like Bitwarden in production pipelines using integrity checks.
Practical steps to detect and mitigate compromised CLI tools like Bitwarden in production pipelines using integrity checks, audit trails, and access controls.
Diagnosis: What to Monitor
-
Unexpected network activity:
- Monitor for outbound connections from CI/CD runners to unknown IPs/domains.
- Use tools like
tcpdump,netstat, or cloud network monitoring (e.g., AWS VPC Flow Logs). - Example:
kubectl exec -it <runner-pod> -- tcpdump -i eth0 host <suspicious-ip>
-
Artifact integrity anomalies:
- Check for unexpected changes in pipeline output (e.g., binaries with mismatched hashes).
- Validate artifacts against pre-signed hashes:
sha256sum <artifact> | diff - <expected-hash>
-
Audit logs:
- Enable detailed logging for CLI tool execution (e.g.,
BW CLI --log-level debug). - Use centralized logging (e.g., Elasticsearch, Loki) to flag suspicious commands like
bw export.
- Enable detailed logging for CLI tool execution (e.g.,
-
Runtime behavior:
- Deploy runtime security tools (e.g., Falco, Tracee) to detect shell spawns or credential accesses:
# Falco rule snippet - rule: Unexpected CLI Activity desc: Detect unauthorized CLI tool usage condition: container.id exists and proc.name = "bw" output: "Unauthorized CLI tool execution (user=%user.name)"
- Deploy runtime security tools (e.g., Falco, Tracee) to detect shell spawns or credential accesses:
Repair: Immediate Actions
-
Isolate affected systems:
- Cordon Kubernetes nodes or pause CI/CD runners:
kubectl cordon <node>
- Cordon Kubernetes nodes or pause CI/CD runners:
-
Revoke compromised credentials:
- Rotate Bitwarden API keys and service account tokens.
- Example for Kubernetes secrets:
kubectl delete secret bitwarden-cli-secret kubectl create secret generic bitwarden-cli-secret --from-literal=API_KEY=<new-key>
-
Scan for persistence:
- Search for backdoors in runner images or pipelines:
docker inspect <runner-image> | grep -i "backdoor"
- Search for backdoors in runner images or pipelines:
Prevention: Policy and Hardening
-
Enforce image provenance:
- Require signed images in CI/CD pipelines using Notary or cosign:
cosign verify --key cosign.pub <runner-image>
- Require signed images in CI/CD pipelines using Notary or cosign:
-
Restrict CLI tool permissions:
- Use least-privilege service accounts (e.g., OpenShift’s
serviceaccountwith minimal roles). - Example policy (Kyverno):
apiVersion: kyverno.io/v1 kind: ClusterPolicy metadata: name: restrict-cli-tools spec: validationFailureAction: enforce rules: - name: check-cli-permissions match: resources: kinds: ["Pod"] validate: pattern: spec: containers: - name: "*-runner" securityContext: runAsNonRoot: true allowPrivilegeEscalation: false
- Use least-privilege service accounts (e.g., OpenShift’s
-
Runtime protection:
- Use read-only volumes for CLI tools to prevent tampering:
volumes: - name: bitwarden-data emptyDir: {} containers: - name: bitwarden-cli volumeMounts: - name: bitwarden-data mountPath: /data readOnly: true
- Use read-only volumes for CLI tools to prevent tampering:
Tooling
- Detection: Falco, Osquery, Sysdig Secure
- Prevention: Kyverno, OPA Gatekeeper, Notary
- Audit: Loki, Grafana, Auditd
Tradeoffs
- False positives: Overly strict policies may block legitimate workflows (e.g., image signing failures during emergencies).
- Overhead: Runtime monitoring adds latency; balance with pipeline performance requirements.
Troubleshooting
- Missing logs: Ensure logging agents (e.g., Fluentd) are running and have sufficient permissions.
- Permission denied: Validate service accounts have
logsandnodesaccess in Kubernetes RBAC. - False negatives: Update detection rules regularly to cover new attack vectors (e.g., novel CLI command patterns).
Validation
- Test detection rules with known bad behavior:
# Simulate a compromise kubectl exec -it <runner-pod> -- bw export --format json > /tmp/creds.json # Verify alert in Falco/monitoring - Validate policy enforcement by deploying non-compliant pods and confirming denials.
Source thread: bitwarden CLI was compromised for ~90 min. what in your pipeline would detect that?

Share this post
Twitter
Google+
Facebook
Reddit
LinkedIn
StumbleUpon
Pinterest
Email