Skip to main content

Bucket Scanner

Bucket Scanner

Declared vs real.
Object Storage security scanner — Yandex Cloud · AWS S3 · Azure · GCS
What you configured · what ACL allows · what the internet can actually reach.

CI PyPI Python 3.11+ Yandex Cloud AWS S3 SARIF 2.1.0 MIT v1.3

FluxTap · Tracefuse · Timeforge · SignShield · Bucket Scanner

Discussions · Issues · #devsecops · #cspm · #object-storage · #yandex-cloud · #aws-s3


Why

Buckets drift. ACL says private, policy leaks public-read. Versioning is off, logging never enabled, a service account key outlived three rotations — and nobody noticed until exfil.

Bucket Scanner walks your Object Storage (Yandex Cloud by default, AWS S3 optional) and surfaces gaps between what you declare and what actually ships:

You declare Bucket Scanner checks
Private bucket Anonymous HEAD / list probe
Encryption at rest Server-side encryption flags per bucket
Audit trail Access logging enabled
Ransomware resilience Versioning + lifecycle sanity
Least privilege SA bindings → blast radius chains

Metadata scan by default. Optional live probe proves reachability — without downloading object bodies.

╔══════════════════════════════════════════════════════════╗
║                      BUCKET SCANNER                      ║
║        declared vs real · object storage truth           ║
╚══════════════════════════════════════════════════════════╝

  score  42  ████████░░░░░░░░░░░░
  CRIT 1  HIGH 4  MED 7  LOW 2  INFO 3

  CHAIN  public-read + no-logging + stale-sa-key → silent exfil path

Part of the FounderB security stack: Tracefuse watches what you ship · FluxTap watches the wire · Bucket Scanner watches what you store.


Install

From PyPI (recommended):

pip install bucket-scanner
# pin: pip install bucket-scanner==1.3.0
bucket-scanner --help

From source (development):

git clone https://github.com/FounderB/BucketScanner.git
cd BucketScanner
python3 -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"
make hooks   # install local git author guard

See docs/PYPI.md for version pins and maintainer publishing.
Start here: docs/QUICKSTART.md · Golden demo: docs/GOLDEN_DEMO.md · Compliance: docs/COMPLIANCE.md

Requirements: Python 3.11+, Yandex Cloud credentials (default) or AWS credentials (--cloud aws). See docs/AWS.md.


AWS S3 (optional)

export AWS_REGION=us-east-1
bucket-scanner scan --cloud aws
bucket-scanner scan --cloud aws --fixture examples/demo-vulnerable/fixture-aws.toml
bucket-scanner doctor --cloud aws

Azure Blob (live + fixture)

pip install "bucket-scanner[azure]"
export AZURE_SUBSCRIPTION_ID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
bucket-scanner scan --cloud azure --folder-id "$AZURE_SUBSCRIPTION_ID"
bucket-scanner scan --cloud azure --fixture examples/demo-vulnerable/fixture-azure.toml
bucket-scanner explain azure/container-public-access

Live scan uses DefaultAzureCredential (env vars, managed identity, Azure CLI). See docs/AZURE.md.

Google Cloud Storage (live + fixture)

pip install "bucket-scanner[gcs]"
export GCP_PROJECT=my-gcp-project
bucket-scanner scan --cloud gcs --folder-id "$GCP_PROJECT"
bucket-scanner scan --cloud gcs --fixture examples/demo-vulnerable/fixture-gcs.toml

See docs/GCS.md.

Live Azure scan: pip install 'bucket-scanner[azure]' — see docs/AZURE.md.


60-second wow

All values under examples/demo-vulnerable/ are labeled FAKE / EXAMPLE.

# Offline demo — no cloud credentials required
bucket-scanner scan --fixture examples/demo-vulnerable/fixture.toml
bucket-scanner scan --fixture examples/demo-vulnerable/fixture.toml --json
bucket-scanner scan --fixture examples/demo-vulnerable/fixture.toml \
  --sarif /tmp/bucket-scanner.sarif --fail-on high

bucket-scanner scan --fixture examples/demo-vulnerable/fixture.toml \
  --repo examples/demo-vulnerable/repo \
  --tracefuse-report examples/demo-vulnerable/tracefuse-report.json \
  --prometheus /tmp/bucket-scanner.prom

# Prometheus + continuous monitoring
bucket-scanner serve --fixture examples/demo-vulnerable/fixture.toml --addr 127.0.0.1:9090

# Prove public exposure (anonymous probe, no object download)
bucket-scanner scan --folder-id b1gxxxxxxxxxx --probe

Expect findings across acl, policy, encryption, logging, versioning, lifecycle, iam, and chains. Exit 1 when policy fails; exit 2 on tool error.


Quick start

export YC_TOKEN=$(yc iam create-token)          # or YC_SERVICE_ACCOUNT_KEY_FILE
export YC_CLOUD_ID=b1g...
export YC_FOLDER_ID=b1g...

bucket-scanner scan --folder-id "$YC_FOLDER_ID"
bucket-scanner scan --folder-id "$YC_FOLDER_ID" --probe --fail-on high
bucket-scanner doctor                           # creds, scopes, API reachability
bucket-scanner explain acl/public-read          # remediation + why

Probe mode sends unauthenticated HTTP requests to bucket endpoints to verify real-world exposure. It never downloads object payloads — only checks reachability metadata.


Features

Detector What it catches
acl public-read, public-read-write, world-open grants
policy Bucket policy statements wider than intent
encryption Missing default encryption / SSE gaps
logging No access logs on sensitive buckets
versioning Versioning disabled on prod-like buckets
lifecycle Aggressive expiration, incomplete multipart cleanup
iam Over-broad SA roles, long-lived static keys
chains Compound risk: public + no logs + no versioning + stale key

Also: health score, bucket-scanner init → .bucket-scanner.toml, doctor / explain, severity overrides, quiet mode for CI, SARIF 2.1.0 for GitHub Code Scanning, diff for Terraform drift.

Terraform drift

bucket-scanner diff examples/demo-vulnerable/terraform \
  --fixture examples/demo-vulnerable/fixture.toml

bucket-scanner scan --folder-id b1g... --terraform ./infra/storage/

Why not the console?

YC Console / manual checklist Bucket Scanner
Scope One bucket at a time Whole folder · repeatable
Proof ACL text says private --probe proves anonymous reachability
Output Screenshots in tickets Redacted human / JSON / SARIF
Policy Spreadsheet --fail-on high · GitHub Action
Chains Siloed findings Misconfig graphs — why it hurts together
Drift Point-in-time CI on every PR · scheduled scans

Use Bucket Scanner when you need one gate that answers “what does this folder actually risk?” — not just “is there a public ACL string somewhere?”


Who is this for?

Audience Fit
Platform / DevSecOps (5–50 people) CI gate on Object Storage drift
Terraform + S3-compatible storage IaC vs live ACL/BPA checks
YC / AWS primary Most tested path; Azure/GCS supported
Full-account CSPM replacement No — narrow storage focus

5-minute path: docs/QUICKSTART.md · Rollout: docs/MIGRATION.md · OIDC CI: docs/OIDC.md


Comparison (honest)

Bucket Scanner Prowler / ScoutSuite Checkov (storage rules)
Focus Object Storage only Full cloud account IaC static analysis
Live API + optional probe Yes Yes No (IaC)
Terraform live drift Yes Limited IaC only
Baseline delta (fail-on new) Yes Varies Varies
Cross-stack (Tracefuse + repo) Yes No Partial
SARIF + compliance JSON Yes Varies Yes

CLI

bucket-scanner init [--preset yc-prod|aws-prod|...] [--force] [path]
bucket-scanner doctor                          # creds, folder access, API health
bucket-scanner explain <rule-id>               # remediation (e.g. acl/public-read)
bucket-scanner scan --folder-id ID             # human report
bucket-scanner scan --folder-id ID --json      # JSON to stdout
bucket-scanner scan --folder-id ID --sarif out.sarif --fail-on high
bucket-scanner scan --folder-id ID --baseline baselines/prod.json --fail-on new
bucket-scanner scan --folder-id ID --write-baseline baselines/prod.json
bucket-scanner scan --folder-id ID --probe     # + anonymous reachability checks
bucket-scanner inspect BUCKET                  # single-bucket deep report
bucket-scanner chain --sa-id ID                # blast radius from one SA
bucket-scanner diff PATH                       # Terraform vs live/fixture
bucket-scanner serve --addr 127.0.0.1:9090     # /metrics + /health
bucket-scanner list --folder-id ID             # inventory summary

Exit codes: 0 clean / below threshold · 1 policy fail · 2 tool error.

Default fail_on in config is high (overridable via --fail-on or .bucket-scanner.toml).


Configuration

bucket-scanner init writes .bucket-scanner.toml:

[scan]
folder_id = "b1gxxxxxxxxxx"
fail_on = "high"
probe = false

[scan.ignore_buckets]
names = ["public-assets-cdn"]

[[scan.severity_overrides]]
rule = "versioning/disabled"
severity = "medium"

See docs/CONFIGURATION.md for full reference.


Architecture

flowchart LR
  CLI["CLI<br/>scan · inspect · chain · doctor"] --> CFG[".bucket-scanner.toml"]
  CFG --> SCAN["scan::run_scan"]
  SCAN --> YC["YC Object Storage API<br/>metadata only"]
  SCAN --> PROBE["probe::anonymous<br/>optional HEAD/list"]
  YC --> DET["checks::*"]
  PROBE --> DET
  DET --> CHAIN["chains::compose"]
  CHAIN --> OUT["report<br/>human · json · sarif"]

Details: docs/ARCHITECTURE.md · docs/CHECKS.md


GitHub Actions

Minimal scan + SARIF upload. Full guide: docs/GITHUB_ACTION.md.

name: bucket-scanner
on:
  pull_request:
  push:
    branches: [main]
  schedule:
    - cron: "0 6 * * *"

permissions:
  contents: read
  security-events: write

jobs:
  scan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with:
          python-version: "3.11"
      - run: pip install .
      - name: Scan YC folder
        env:
          YC_TOKEN: ${{ secrets.YC_TOKEN }}
          YC_FOLDER_ID: ${{ secrets.YC_FOLDER_ID }}
        run: |
          bucket-scanner scan --folder-id "$YC_FOLDER_ID" \
            --sarif bucket-scanner.sarif --fail-on high -q
      - name: Upload SARIF
        if: always()
        uses: github/codeql-action/upload-sarif@v3
        with:
          sarif_file: bucket-scanner.sarif

Security promises

  • Metadata by default — list buckets, ACLs, policies, settings; no bulk object download.
  • Probe is opt-in — anonymous HTTP checks only when you pass --probe.
  • Redaction — SA key fragments, tokens, and sensitive URLs redacted in all report formats.
  • Offline fixtures — examples/demo-vulnerable/ uses clearly labeled FAKE/EXAMPLE values only.

See SECURITY.md and docs/AUDIT.md.


Roadmap

  • Tracefuse hook — leaked YC_* in repo → cross-finding
  • Prometheus exporter + Grafana dashboard
  • Scheduled drift alerts (Telegram / webhook)
  • AWS S3 backend (optional second cloud)
  • Multi-region AWS inventory (per-bucket region resolution)
  • Scheduled scan profiles in config
  • CI/CD profile workflows (Action + scheduled matrix)
  • Baseline/delta + suppressions for production CI gates
  • Security hardening + audit docs (v0.11)
  • PyPI package (pip install bucket-scanner)
  • Azure Blob live scan (pip install bucket-scanner[azure])
  • GCS backend (fixture-first)
  • GCS live scan (pip install bucket-scanner[gcs])
  • Golden demo walkthrough (docs/GOLDEN_DEMO.md)
  • SARIF compliance tags (docs/COMPLIANCE.md)
  • v1.0 stable — four-cloud live scan + PyPI + CI gates
  • v1.1 — Terraform Azure/GCS drift, compliance export, Tracefuse polish
  • v1.2 field deployment — prod profiles, baselines/, OIDC workflows (AWS/Azure/GCS), Grafana VM guide, multi-scope Azure/GCS

Community

Channel Link
GitHub Discussions FounderB/BucketScanner/discussions
Issues FounderB/BucketScanner/issues

GitHub topics: devsecops · cspm · object-storage · yandex-cloud · amazon-s3 · sarif · python

FounderB stack: Tracefuse (supply chain) · FluxTap (wire) · Bucket Scanner (object storage)


License

MIT © FounderB — LICENSE.

Contributing

CONTRIBUTING.md · CHANGELOG.md

Release files for bucket-scanner 1.3.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for bucket-scanner 1.3.0
File Size Uploaded
bucket_scanner-1.3.0.tar.gz 71.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for bucket-scanner 1.3.0
File Interpreter ABI Platform
bucket_scanner-1.3.0-py3-none-any.whl Python 3 none any Details

Total release size: 135.5 kB

Release files / bucket_scanner-1.3.0.tar.gz

Download URL bucket_scanner-1.3.0.tar.gz
Size 71.1 kB
Tags Source
SHA-256 checksum
How to use checksums
9245604c93e4a3b4c6a55ceab51c26cbb85b5477241519e542f809b5e03f6367
BLAKE2b-256 checksum
How to use checksums
0dfc32f0485db4246b2a5139b69eef95b88cefc176701e7c68681f4d553961b9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.14

Release files / bucket_scanner-1.3.0-py3-none-any.whl

Download URL bucket_scanner-1.3.0-py3-none-any.whl
Size 64.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
51f400a5e25b3060d3b23a1128ed89dc65fe78c1525cba005472b6bef33da569
BLAKE2b-256 checksum
How to use checksums
2d1b41a958efe70de80fc5834a5d07b993f026160dfd5ef5c0f68afc39bbd43d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.14

Release history Release notifications | RSS feed

1.9.2

2 release files

1.9.1

2 release files

1.9.0

2 release files

1.8.1

2 release files

1.8.0

2 release files

1.7.1

2 release files

1.7.0

2 release files

1.6.0

2 release files

1.5.0

2 release files

1.3.1

2 release files

This release

1.3.0 This release

2 release files

1.2.0

2 release files

1.1.0

2 release files

1.0.0

2 release files

0.15.0

2 release files

0.14.0

2 release files

0.13.0

2 release files

0.12.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page