- Shell 100%
| collect-images | ||
| collect-resources | ||
| collect-secret-access | ||
| find-externally-exposed | ||
| find-image-issues | ||
| find-privileged-workloads | ||
| find-resource-gaps | ||
| find-risky-service-accounts | ||
| find-sensitive-data | ||
| get-permissions-for | ||
| README.md | ||
Repo Description
Collection of Kubernetes utilities I've written. Some are certaintly more useful than others. May be useful to you, may not.
Synopsis of Tools
| Name | Description |
|---|---|
| get-permissions-for | Basically a full replacement for kubectl auth can-i --list that includes "blame". Handles all the edge cases. Useful for when you need to report on a specific permission, when you only have local files, or only have access via impersonation. You need all the [Cluster]Role[Binding] files. |
| collect-resources | One-shot kubectl collector. Writes all relevant resources to a data-directory tree under resources/ (including ServiceAccounts and Secret .data values, which the downstream tools operate on — pass --strip-secret-values to omit them). Auto-detects available CRDs (Istio, Gateway API, OpenShift Routes, Traefik, and secrets-injection operators) and skips missing ones gracefully. Run this first; the find-* tools read from the tree. |
| collect-images | Pulls the actual container images running on nodes straight from the node runtime (containerd / CRI-O / Docker) via a privileged debug pod, deduplicated by imageID. Writes image archives and per-pod metadata into the tree for find-image-issues. Requires cluster-admin. |
| collect-secret-access | For each pod/container, enumerates every method by which secrets are made available — K8s-native mounts/env, Vault (Agent Injector + Secrets Operator), CSI Secret Store, External Secrets, Sealed Secrets, Doppler, Infisical, and AWS IRSA / GCP / Azure Workload Identity. Writes structured findings per method, and collected secret/configmap values into the tree for find-sensitive-data. |
| find-externally-exposed | Identifies pods/workloads reachable from outside the cluster via Services (NodePort/LoadBalancer/ExternalName), Ingresses, and mesh/ingress resources (Istio, Gateway API, OpenShift Routes, Traefik). --emit-pods produces a pod filter list for chaining into the other find-* tools. |
| find-sensitive-data | Detects hardcoded/plaintext secrets across ConfigMap data, pod env literals, container command/args, annotations, collected tree secret values, and image-layer findings. Uses gitleaks for text detection and parses trivy image-secret output. Requires gitleaks. |
| find-privileged-workloads | Flags pods/workloads with dangerous security-context settings (hostNetwork/hostPID/hostIPC, privileged, runAsUser=0, missing readOnlyRootFilesystem/seccompProfile, hostPath volumes, dangerous added capabilities) at both pod and container level. |
| find-risky-service-accounts | Identifies pods whose ServiceAccounts hold RBAC permissions enabling privilege escalation or credential theft (read secrets, exec into pods, mint SA tokens, escalate/bind roles, node proxy, wildcards). Builds the SA→bindings→rules map from [Cluster]Role[Binding] files with "blame". |
| find-image-issues | Scans collected image archives for vulnerabilities and embedded secrets (trivy), generates SBOMs (syft), and runs manifest-hygiene checks (:latest, untagged, no digest pin, unqualified/unexpected registry). Works against the tree or a single --scan-archive. Requires trivy and syft. |
| find-resource-gaps | Identifies containers missing CPU/memory requests and/or limits across pods, deployments, daemonsets, and statefulsets. |
All collect-*/find-* tools share a common --data-dir tree (populated by collect-resources), support -a/--assume to resolve standard filenames from it, and accept --pod-list (one namespace/podname per line) to chain a filtered set of pods between tools.
Execution Flow
The collect-* tools write into a shared --data-dir tree; the find-* tools read from it. The intended order is collect first, then find. Once collected, the find-* tools run entirely offline against the tree.
flowchart TD
cr["collect-resources -D ./dump<br/>(run first — writes dump/resources/*.json)"]
ci["collect-images -D ./dump -a<br/>(needs cluster-admin; writes dump/images/*)"]
csa["collect-secret-access -D ./dump -a<br/>(writes dump/pods/.../secrets/ + values/)"]
fii["find-image-issues -D ./dump -a<br/>(writes trivy-secrets.json into the tree)"]
fsd["find-sensitive-data -D ./dump -a<br/>(reads tree secret values + image-layer findings)"]
other["find-externally-exposed<br/>find-privileged-workloads<br/>find-risky-service-accounts<br/>find-resource-gaps<br/>(-D ./dump -a)"]
cr -->|optional| ci
cr -->|optional| csa
cr --> other
ci --> fii
csa --> fsd
fii -->|image-layer secret findings| fsd
subgraph collect["1. Collect (online — needs cluster access)"]
cr
ci
csa
end
subgraph find["2. Find (offline — reads the tree)"]
fii
fsd
other
end
1. Collect (online — needs cluster access):
# Required first step. Snapshots the cluster into ./dump/resources/.
./collect-resources -D ./dump # add -n <ns> to scope, -c <ctx> to pick a context
# Optional. Pull running image archives off the nodes (needs cluster-admin).
./collect-images -D ./dump -a
# Optional. Map every secret-injection method per pod and stage values for scanning.
./collect-secret-access -D ./dump -a
2. Find (offline — reads the tree):
./find-externally-exposed -D ./dump -a
./find-privileged-workloads -D ./dump -a
./find-risky-service-accounts -D ./dump -a
./find-resource-gaps -D ./dump -a
./find-image-issues -D ./dump -a # needs collect-images first; trivy + syft
./find-sensitive-data -D ./dump -a # needs gitleaks; best after collect-secret-access + find-image-issues
Ordering notes:
collect-resourcesis the only mandatory step; everything else reads what it wrote.find-image-issuesrequirescollect-imagesto have run, and writestrivy-secrets.jsonback into the tree — run it beforefind-sensitive-dataso the latter can fold in image-layer secret findings.find-sensitive-datais most complete after bothcollect-secret-access(stages collected secret/configmap values) andfind-image-issueshave run.- All
find-*tools are read-only and offline; rerun them freely without re-collecting.
3. Chaining a focused subset: find-externally-exposed --emit-pods writes a namespace/podname list that every other tool accepts via --pod-list, so you can narrow an audit to just the internet-facing pods:
./find-externally-exposed -D ./dump -a --emit-pods > exposed-pods.txt
./find-risky-service-accounts -D ./dump -a --pod-list exposed-pods.txt
./find-sensitive-data -D ./dump -a --pod-list exposed-pods.txt
./find-image-issues -D ./dump -a --pod-list exposed-pods.txt
Author: Michael Mitchell awildbeard@byte.farm