One storage security audit suite for Azure, AWS, and GCP

One storage security audit suite for Azure, AWS, and GCP

Every cloud environment I've touched has the same two storage problems: a bucket someone made public and forgot, and a storage account that should be behind a private endpoint but isn't. The checks differ slightly per provider, but the question is always the same — "is this storage reachable by someone who shouldn't see it?" I got tired of answering that question with ad-hoc scripts that died in one environment and were rewritten in the next. So I built one suite that covers all three clouds and writes every result to the same CSV/JSON shape. What it checks AWS (S3) — the three ways a bucket becomes public: Public Access Block fully enabled Bucket policy reported as IsPublic ACL grants to AllUsers / AuthenticatedUsers Plus a security-config audit for default encryption (SSE-S3/SSE-KMS) and versioning. GCP (Cloud Storage) — IAM bindings to allUsers / allAuthenticatedUsers, uniform bucket-level access, and public access prevention. Azure (Storage Accounts) — accounts with and without Private Endpoints, plus TLS version, secure transfer, and public network access posture. Everything is read-only. No module creates, modifies, or deletes anything — you run it, get a report, fix what it flags. Running it # AWS: only the public buckets, as JSON python aws/s3/audit-public-buckets/audit_public_buckets.py --only-public --format json --output-file public.json # GCP: security configuration matrix python gcp/storage/audit-security-config/audit_bucket_security.py --project my-project --output-file compliance.csv # Azure: storage accounts with no private endpoint ./azure/storage/audit-missing-private-endpoints/audit-storage-without-pe.ps1 -OutputPath exposed.csv Enter fullscreen mode Exit fullscreen mode The Azure side also ships Bash and KQL variants so you can run the same check from Resource Graph in the portal. The report contract Every module writes the same shape — CSV or JSON — with a boolean "finding" column you actually act on: Provider Finding column AWS public buckets is_public AWS / GCP security config hardened GCP public IAM public Azure (no PE) PrivateEndpointCount == 0 Summaries go to stderr, so stdout stays clean for automation. Redacted example outputs for every module are in docs/samples/, and the full field contract is in docs/report-format.md. The bug that cost me half a day The AWS and GCP scripts in each provider are named the same — audit_public_buckets.py, audit_bucket_security.py. That's fine until your test files import both. Python imports by module name, so once pytest cached the AWS version, the GCP tests silently imported the wrong code and failed with the most confusing TypeError. The fix was loading the modules by explicit file path instead of leaning on sys.path: spec = importlib.util.spec_from_file_location(name, path) module = importlib.util.module_from_spec(spec) spec.loader.exec_module(module) Enter fullscreen mode Exit fullscreen mode Half a day, gone, over a naming collision. Keeping it honest Pester validates the Azure modules (parse, parameters, read-only guarantees) pytest (mocked cloud clients) covers the AWS/GCP modules CI runs PSScriptAnalyzer, ShellCheck, ruff, markdownlint, and yamllint on every push Test coverage sits at 85% and is published via Codecov The first CI run failed in four jobs at once — the lesson being that lint rules move under you (a newer PSScriptAnalyzer started flagging Write-Host as a warning I'd never seen before). Where it lives The whole thing is free and open source: https://github.com/priyaranjan-sahu/multi-cloud-automation-scripts If you manage storage across more than one cloud, it's probably a better starting point than whatever script you were about to rewrite for the fifth time. PRs and issues welcome.

Original Source

Read the full article at Dev →

KhanList aggregates and links to publicly available news content. We do not host full articles from third-party sources. Always verify important information with original sources.