Skip to content

Latest commit

 

History

14 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Lab 08: Conjur Secrets on Kubernetes plus KubiScan RBAC Audit

RBAC linter catches the planted roles in both input shapes

tests

Pods get their secrets from Conjur so none holds a static credential. Then a second check hunts the RBAC permissions that make perfect secrets management pointless. Both halves, because doing one without the other is theatre.

Domains CyberArk/Idira, Linux, Kubernetes
Built on cyberark/conjur + helm chart, cyberark/KubiScan
Cost $0 (local kind/minikube). Runtime ~4 hours
Status Run against a real kind cluster. The linter silently missed every planted role on live kubectl output; fixed, 15 findings now (output in findings/). KubiScan cross-check still pending

Situation

You can do secrets perfectly, with Conjur brokering every credential and nothing static in a pod, and still be wide open. A service account that can escalate, bind, or create pods can mint itself a token that reads everything. Secrets injection and RBAC are two halves of one problem.

Task

Do both halves: the clean secrets path, and the audit that checks whether the cluster's permissions quietly undo it.

Action

KubiScan (CyberArk's tool) runs against the live cluster and finds risky subjects, roles, and pods from the real permissions. I also wrote an offline pre check (scripts/rbac_lint.py) that reads the RBAC YAML and flags the same escalation tricks before anything is applied, so they are caught at PR time.

To have something to catch, k8s/risky-rbac.yaml plants six escalation tricks, each of which beats good secrets hygiene:

Risk Why it beats secrets injection
escalate grant yourself any permission
bind bind full admin to yourself
secrets read just read all the secrets directly
pods create schedule a pod wearing a privileged token
wildcard everything full admin by another name
SA to wildcard binding makes the wildcard live

Result

Run against a real kind cluster, the linter catches every planted role — after a run that first proved why it's needed. Pointed at live kubectl -o json output, the first version reported No risky RBAC found on a cluster holding four cluster-admin-equivalent roles: kubectl wraps everything in a single kind: List document the linter did not descend into. Every unit test had passed the whole time, because every test fed it a hand-written manifest — the one shape it never meets in production. Fixed, and it now surfaces 15 findings, separating the planted roles from Kubernetes' own built-ins by label rather than by name.

15 tests plus a CI canary that runs the linter against this repo's own dangerous manifest in both input shapes and fails if either comes back clean — so a linter that silently stops detecting can never ship green again. kubeconform schema-checks every manifest alongside it. Full output in findings/live-cluster-run.txt.

What I did not build

Conjur and KubiScan are CyberArk's. The workload, the planted RBAC fixture, the offline linter, and the tests are mine.

Run it

make cluster
make conjur
make deploy
make apply-rbac
make kubiscan
python scripts/rbac_lint.py k8s/*.yaml   # offline cross check
make destroy

Needs kind or minikube, kubectl, Helm, Python 3.

Findings

findings/ holds the live-cluster run: the linter silently missing every planted role on kubectl output, then catching all 15 after the fix. LAB-NOTES.md is the log.

License

Lab code: MIT (LICENSE). Conjur and KubiScan keep their licenses, credited above.

About

Conjur secrets on Kubernetes + KubiScan RBAC audit

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages