Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Bastion — Azure Access & Identity Baseline

CI

A scanner and an infrastructure baseline for untangling who can access what across a multi-subscription Azure estate: shared secrets out, managed identities in; direct privileged grants out, group-based RBAC with PIM in; Key Vault access policies out, RBAC authorization in. The scanner reads the estate, evaluates it against the baseline, and emits findings with remediations — as JSON for the dashboard or SARIF for code-scanning UIs.

Reference implementation. Real, working engineering written to demonstrate the approach — not a client deliverable. The estate in the fixtures and sample report is illustrative; the rules, scanner and infrastructure are not. Scanning a live estate needs Reader on the target subscriptions.

The baseline

Rule Check Severity
BAS-001 Credentials in app settings (passwords, account keys — Key Vault references exempt) Critical
BAS-002 Long-lived or expired service-principal secrets (federated credentials exempt) High
BAS-003 Owner/Contributor at subscription scope granted directly to a user or SP High
BAS-004 Compute without a managed identity Medium
BAS-005 Key Vault still on access policies instead of RBAC Medium
BAS-006 Storage account still allows shared-key access High
BAS-007 More than a break-glass number of subscription Owners Medium

Each rule is one pure class over an estate snapshot (src/Bastion.Rules) with its own tests — adding a check is a class and a fixture, not a refactor.

Scan

dotnet run --project src/Bastion.Scanner -- rules              # list the baseline
dotnet run --project src/Bastion.Scanner -- scan               # scan visible subscriptions (JSON)
dotnet run --project src/Bastion.Scanner -- scan --format sarif --output findings.sarif
dotnet run --project src/Bastion.Scanner -- scan --save-snapshot estate.json

scan walks every subscription visible to DefaultAzureCredential (read-only), builds a snapshot, runs the rules, and exits non-zero if anything High or Critical is open — so a scheduled pipeline fails on drift. Open the JSON report in the dashboard (npm run dev).

Try it without an Azure subscription

A captured snapshot can be analysed offline — no credentials, no cloud:

dotnet run --project src/Bastion.Scanner -- analyze samples/estate.json --format markdown

samples/estate.json is a deliberately messy two-subscription estate; the command produces the one-page access review (13 findings) and exits 2 because Critical findings are open. Service-principal credentials come from Microsoft Graph via GraphServicePrincipalReader when the scanning identity holds Application.Read.All.

The baseline as code

infra/ contains the Bicep that is the remediation:

Build & test

Prerequisites, a clean-machine setup, the permissions a live scan needs and troubleshooting are in INSTALL.md. Short version:

dotnet test Bastion.sln          # 15 rule-engine tests
cd web && npm ci && npm run build

Both run in CI on every push, plus az bicep build over every module.


Design and code by Nick Zivkovic.

About

Bastion — a UI concept for Azure access & identity governance across a multi-subscription estate (static mockup).

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages