Copy-paste-runnable examples. Install Bastion first (pip install bastion-k8s,
or pip install -e ".[dev]" from a checkout), then run any of these from the
repository root.
| File | What it is |
|---|---|
manifests/vulnerable.yaml |
A two-hop escalation: ci-runner can create pods in build, so it can run a pod as deployer, who can read every Secret in the cluster. Every grant is individually defensible; together they are a route. |
manifests/hardened.yaml |
The same two accounts with the escalation removed — ci-runner can only view pods, and deployer reads one named Secret. Bastion reports no path. |
Both are inert: they declare RBAC, they run nothing.
# Scan and write a self-contained HTML report
bastion scan examples/manifests/vulnerable.yaml
# The question people actually ask
bastion paths examples/manifests/vulnerable.yaml --from ci-runner --to secrets
# Gate on absolute state (exit 1 if any P0 finding)
bastion scan examples/manifests/vulnerable.yaml --format sarif --fail-on P0
# Does the change introduce a NEW route? (hardened -> vulnerable does)
bastion diff examples/manifests/hardened.yaml examples/manifests/vulnerable.yaml --fail-on-new-path| Script | Shows |
|---|---|
python_api.py |
The one-call engine.scan(...), then reading findings, paths, and the posture score programmatically. |
find_paths.py |
Filtering escalation paths to a chosen terminal — the API form of bastion paths. |
diff_gate.py |
The CI gate in Python: fail only on newly introduced critical paths. Exits 1 on the vulnerable manifest. |
python examples/python_api.py
python examples/find_paths.py
python examples/diff_gate.py ; echo "exit code: $?"github-actions-gate.yml is a ready-to-use workflow
that blocks a pull request introducing a new escalation path. More recipes for
GitLab, Jenkins, and pre-commit are in docs/CI_RECIPES.md.