bucket-scanner 0.12.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- bucket_scanner-0.12.0/LICENSE +21 -0
- bucket_scanner-0.12.0/PKG-INFO +372 -0
- bucket_scanner-0.12.0/README.md +335 -0
- bucket_scanner-0.12.0/pyproject.toml +75 -0
- bucket_scanner-0.12.0/setup.cfg +4 -0
- bucket_scanner-0.12.0/src/bucket_scanner/__init__.py +3 -0
- bucket_scanner-0.12.0/src/bucket_scanner/auth.py +156 -0
- bucket_scanner-0.12.0/src/bucket_scanner/aws/__init__.py +0 -0
- bucket_scanner-0.12.0/src/bucket_scanner/aws/iam.py +71 -0
- bucket_scanner-0.12.0/src/bucket_scanner/aws/s3.py +104 -0
- bucket_scanner-0.12.0/src/bucket_scanner/chains.py +107 -0
- bucket_scanner-0.12.0/src/bucket_scanner/checks.py +397 -0
- bucket_scanner-0.12.0/src/bucket_scanner/cli.py +638 -0
- bucket_scanner-0.12.0/src/bucket_scanner/cloud.py +24 -0
- bucket_scanner-0.12.0/src/bucket_scanner/config.py +281 -0
- bucket_scanner-0.12.0/src/bucket_scanner/diff.py +153 -0
- bucket_scanner-0.12.0/src/bucket_scanner/doctor.py +93 -0
- bucket_scanner-0.12.0/src/bucket_scanner/explain.py +158 -0
- bucket_scanner-0.12.0/src/bucket_scanner/fixture.py +47 -0
- bucket_scanner-0.12.0/src/bucket_scanner/gate.py +133 -0
- bucket_scanner-0.12.0/src/bucket_scanner/models.py +117 -0
- bucket_scanner-0.12.0/src/bucket_scanner/notify.py +107 -0
- bucket_scanner-0.12.0/src/bucket_scanner/probe.py +51 -0
- bucket_scanner-0.12.0/src/bucket_scanner/report/__init__.py +0 -0
- bucket_scanner-0.12.0/src/bucket_scanner/report/human.py +96 -0
- bucket_scanner-0.12.0/src/bucket_scanner/report/json_report.py +9 -0
- bucket_scanner-0.12.0/src/bucket_scanner/report/prometheus.py +52 -0
- bucket_scanner-0.12.0/src/bucket_scanner/report/sarif.py +93 -0
- bucket_scanner-0.12.0/src/bucket_scanner/s3_common.py +96 -0
- bucket_scanner-0.12.0/src/bucket_scanner/scan.py +351 -0
- bucket_scanner-0.12.0/src/bucket_scanner/scope.py +5 -0
- bucket_scanner-0.12.0/src/bucket_scanner/secrets.py +161 -0
- bucket_scanner-0.12.0/src/bucket_scanner/serve.py +121 -0
- bucket_scanner-0.12.0/src/bucket_scanner/terraform.py +233 -0
- bucket_scanner-0.12.0/src/bucket_scanner/tracefuse.py +61 -0
- bucket_scanner-0.12.0/src/bucket_scanner/yc/__init__.py +0 -0
- bucket_scanner-0.12.0/src/bucket_scanner/yc/management.py +63 -0
- bucket_scanner-0.12.0/src/bucket_scanner/yc/s3.py +45 -0
- bucket_scanner-0.12.0/src/bucket_scanner.egg-info/PKG-INFO +372 -0
- bucket_scanner-0.12.0/src/bucket_scanner.egg-info/SOURCES.txt +56 -0
- bucket_scanner-0.12.0/src/bucket_scanner.egg-info/dependency_links.txt +1 -0
- bucket_scanner-0.12.0/src/bucket_scanner.egg-info/entry_points.txt +2 -0
- bucket_scanner-0.12.0/src/bucket_scanner.egg-info/requires.txt +15 -0
- bucket_scanner-0.12.0/src/bucket_scanner.egg-info/top_level.txt +1 -0
- bucket_scanner-0.12.0/tests/test_aws.py +297 -0
- bucket_scanner-0.12.0/tests/test_azure.py +81 -0
- bucket_scanner-0.12.0/tests/test_checks.py +148 -0
- bucket_scanner-0.12.0/tests/test_ci_profiles.py +74 -0
- bucket_scanner-0.12.0/tests/test_cli.py +22 -0
- bucket_scanner-0.12.0/tests/test_gate.py +206 -0
- bucket_scanner-0.12.0/tests/test_integration.py +135 -0
- bucket_scanner-0.12.0/tests/test_package.py +16 -0
- bucket_scanner-0.12.0/tests/test_profiles.py +162 -0
- bucket_scanner-0.12.0/tests/test_scanner.py +109 -0
- bucket_scanner-0.12.0/tests/test_security.py +57 -0
- bucket_scanner-0.12.0/tests/test_serve.py +83 -0
- bucket_scanner-0.12.0/tests/test_terraform.py +67 -0
- bucket_scanner-0.12.0/tests/test_v03.py +119 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 FounderB
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,372 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: bucket-scanner
|
|
3
|
+
Version: 0.12.0
|
|
4
|
+
Summary: Declared vs real — Object Storage security scanner (Yandex Cloud + AWS S3 + Azure preview)
|
|
5
|
+
Author: FounderB
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/FounderB/BucketScanner
|
|
8
|
+
Project-URL: Repository, https://github.com/FounderB/BucketScanner
|
|
9
|
+
Project-URL: Issues, https://github.com/FounderB/BucketScanner/issues
|
|
10
|
+
Keywords: yandex-cloud,aws,s3,object-storage,bucket-scanner,security,cspm,devsecops,sarif
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
|
+
Classifier: Environment :: Console
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: Intended Audience :: System Administrators
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Classifier: Topic :: Security
|
|
18
|
+
Classifier: Topic :: System :: Systems Administration
|
|
19
|
+
Requires-Python: >=3.11
|
|
20
|
+
Description-Content-Type: text/markdown
|
|
21
|
+
License-File: LICENSE
|
|
22
|
+
Requires-Dist: boto3>=1.34
|
|
23
|
+
Requires-Dist: click>=8.1
|
|
24
|
+
Requires-Dist: httpx>=0.27
|
|
25
|
+
Requires-Dist: pyjwt[crypto]>=2.8
|
|
26
|
+
Requires-Dist: pydantic>=2.7
|
|
27
|
+
Requires-Dist: rich>=13.7
|
|
28
|
+
Provides-Extra: dev
|
|
29
|
+
Requires-Dist: bandit>=1.7; extra == "dev"
|
|
30
|
+
Requires-Dist: build>=1.2; extra == "dev"
|
|
31
|
+
Requires-Dist: pip-audit>=2.7; extra == "dev"
|
|
32
|
+
Requires-Dist: pytest>=8.2; extra == "dev"
|
|
33
|
+
Requires-Dist: pytest-cov>=5.0; extra == "dev"
|
|
34
|
+
Requires-Dist: ruff>=0.5; extra == "dev"
|
|
35
|
+
Requires-Dist: twine>=5.0; extra == "dev"
|
|
36
|
+
Dynamic: license-file
|
|
37
|
+
|
|
38
|
+
<p align="center">
|
|
39
|
+
<img src="assets/bucket-scanner-icon.png" alt="Bucket Scanner" width="160" height="160"/>
|
|
40
|
+
</p>
|
|
41
|
+
|
|
42
|
+
<h1 align="center">Bucket Scanner</h1>
|
|
43
|
+
|
|
44
|
+
<p align="center">
|
|
45
|
+
<strong>Declared vs real.</strong> Object Storage security scanner (Yandex Cloud + AWS S3 + Azure preview).<br/>
|
|
46
|
+
What you configured · what ACL allows · what the internet can actually reach.
|
|
47
|
+
</p>
|
|
48
|
+
|
|
49
|
+
<p align="center">
|
|
50
|
+
<a href="https://github.com/FounderB/BucketScanner/actions"><img src="https://img.shields.io/github/actions/workflow/status/FounderB/BucketScanner/ci.yml?branch=main&label=CI&style=flat-square" alt="CI"/></a>
|
|
51
|
+
<img src="https://img.shields.io/badge/python-3.11%2B-2ee6a6?style=flat-square" alt="Python 3.11+"/>
|
|
52
|
+
<img src="https://img.shields.io/badge/Yandex%20Cloud-Object%20Storage-5282FF?style=flat-square" alt="Yandex Cloud"/>
|
|
53
|
+
<img src="https://img.shields.io/badge/AWS-S3-FF9900?style=flat-square" alt="AWS S3"/>
|
|
54
|
+
<img src="https://img.shields.io/badge/SARIF-2.1.0-2ee6a6?style=flat-square" alt="SARIF 2.1.0"/>
|
|
55
|
+
<a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-5eead4?style=flat-square" alt="MIT"/></a>
|
|
56
|
+
<img src="https://img.shields.io/badge/scan-metadata%20default-darkgrey?style=flat-square" alt="Metadata default"/>
|
|
57
|
+
</p>
|
|
58
|
+
|
|
59
|
+
<p align="center">
|
|
60
|
+
<a href="https://github.com/FounderB/FluxTap">FluxTap</a> ·
|
|
61
|
+
<a href="https://github.com/FounderB/Tracefuse">Tracefuse</a> ·
|
|
62
|
+
<a href="https://github.com/FounderB/Timeforge">Timeforge</a> ·
|
|
63
|
+
<a href="https://github.com/FounderB/SignShield">SignShield</a> ·
|
|
64
|
+
<b>Bucket Scanner</b>
|
|
65
|
+
</p>
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
## Why
|
|
70
|
+
|
|
71
|
+
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.
|
|
72
|
+
|
|
73
|
+
Bucket Scanner walks your **Object Storage** (Yandex Cloud by default, **AWS S3** optional) and surfaces gaps between **what you declare** and **what actually ships**:
|
|
74
|
+
|
|
75
|
+
| You declare | Bucket Scanner checks |
|
|
76
|
+
|-------------|----------------------|
|
|
77
|
+
| Private bucket | Anonymous `HEAD` / list probe |
|
|
78
|
+
| Encryption at rest | Server-side encryption flags per bucket |
|
|
79
|
+
| Audit trail | Access logging enabled |
|
|
80
|
+
| Ransomware resilience | Versioning + lifecycle sanity |
|
|
81
|
+
| Least privilege | SA bindings → blast radius chains |
|
|
82
|
+
|
|
83
|
+
Metadata scan by default. Optional live probe proves reachability — **without downloading object bodies**.
|
|
84
|
+
|
|
85
|
+
```
|
|
86
|
+
╔══════════════════════════════════════════════════════════╗
|
|
87
|
+
║ BUCKET SCANNER ║
|
|
88
|
+
║ declared vs real · object storage truth ║
|
|
89
|
+
╚══════════════════════════════════════════════════════════╝
|
|
90
|
+
|
|
91
|
+
score 42 ████████░░░░░░░░░░░░
|
|
92
|
+
CRIT 1 HIGH 4 MED 7 LOW 2 INFO 3
|
|
93
|
+
|
|
94
|
+
CHAIN public-read + no-logging + stale-sa-key → silent exfil path
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Part of the **FounderB security stack**: [Tracefuse](https://github.com/FounderB/Tracefuse) watches what you ship · [FluxTap](https://github.com/FounderB/FluxTap) watches the wire · **Bucket Scanner** watches what you store.
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
## Install
|
|
102
|
+
|
|
103
|
+
**From PyPI** (recommended):
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
pip install bucket-scanner
|
|
107
|
+
bucket-scanner --help
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
**From source** (development):
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
git clone https://github.com/FounderB/BucketScanner.git
|
|
114
|
+
cd BucketScanner
|
|
115
|
+
python3 -m venv .venv && source .venv/bin/activate
|
|
116
|
+
pip install -e ".[dev]"
|
|
117
|
+
make hooks # install local git author guard
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
See [docs/PYPI.md](docs/PYPI.md) for version pins and maintainer publishing.
|
|
121
|
+
|
|
122
|
+
**Requirements:** Python **3.11+**, Yandex Cloud credentials (default) or AWS credentials (`--cloud aws`). See [docs/AWS.md](docs/AWS.md).
|
|
123
|
+
|
|
124
|
+
---
|
|
125
|
+
|
|
126
|
+
## AWS S3 (optional)
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
export AWS_REGION=us-east-1
|
|
130
|
+
bucket-scanner scan --cloud aws
|
|
131
|
+
bucket-scanner scan --cloud aws --fixture examples/demo-vulnerable/fixture-aws.toml
|
|
132
|
+
bucket-scanner doctor --cloud aws
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
## Azure Blob (fixture-only preview)
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
bucket-scanner scan --cloud azure --fixture examples/demo-vulnerable/fixture-azure.toml
|
|
139
|
+
bucket-scanner explain azure/container-public-access
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
Live Azure inventory is planned; see [docs/AZURE.md](docs/AZURE.md).
|
|
143
|
+
|
|
144
|
+
---
|
|
145
|
+
|
|
146
|
+
## 60-second wow
|
|
147
|
+
|
|
148
|
+
All values under `examples/demo-vulnerable/` are labeled **FAKE / EXAMPLE**.
|
|
149
|
+
|
|
150
|
+
```bash
|
|
151
|
+
# Offline demo — no cloud credentials required
|
|
152
|
+
bucket-scanner scan --fixture examples/demo-vulnerable/fixture.toml
|
|
153
|
+
bucket-scanner scan --fixture examples/demo-vulnerable/fixture.toml --json
|
|
154
|
+
bucket-scanner scan --fixture examples/demo-vulnerable/fixture.toml \
|
|
155
|
+
--sarif /tmp/bucket-scanner.sarif --fail-on high
|
|
156
|
+
|
|
157
|
+
bucket-scanner scan --fixture examples/demo-vulnerable/fixture.toml \
|
|
158
|
+
--repo examples/demo-vulnerable/repo \
|
|
159
|
+
--tracefuse-report examples/demo-vulnerable/tracefuse-report.json \
|
|
160
|
+
--prometheus /tmp/bucket-scanner.prom
|
|
161
|
+
|
|
162
|
+
# Prometheus + continuous monitoring
|
|
163
|
+
bucket-scanner serve --fixture examples/demo-vulnerable/fixture.toml --addr 127.0.0.1:9090
|
|
164
|
+
|
|
165
|
+
# Prove public exposure (anonymous probe, no object download)
|
|
166
|
+
bucket-scanner scan --folder-id b1gxxxxxxxxxx --probe
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
Expect findings across **acl**, **policy**, **encryption**, **logging**, **versioning**, **lifecycle**, **iam**, and **chains**. Exit `1` when policy fails; exit `2` on tool error.
|
|
170
|
+
|
|
171
|
+
---
|
|
172
|
+
|
|
173
|
+
## Quick start
|
|
174
|
+
|
|
175
|
+
```bash
|
|
176
|
+
export YC_TOKEN=$(yc iam create-token) # or YC_SERVICE_ACCOUNT_KEY_FILE
|
|
177
|
+
export YC_CLOUD_ID=b1g...
|
|
178
|
+
export YC_FOLDER_ID=b1g...
|
|
179
|
+
|
|
180
|
+
bucket-scanner scan --folder-id "$YC_FOLDER_ID"
|
|
181
|
+
bucket-scanner scan --folder-id "$YC_FOLDER_ID" --probe --fail-on high
|
|
182
|
+
bucket-scanner doctor # creds, scopes, API reachability
|
|
183
|
+
bucket-scanner explain acl/public-read # remediation + why
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
> **Probe mode** sends unauthenticated HTTP requests to bucket endpoints to verify real-world exposure. It never downloads object payloads — only checks reachability metadata.
|
|
187
|
+
|
|
188
|
+
---
|
|
189
|
+
|
|
190
|
+
## Features
|
|
191
|
+
|
|
192
|
+
| Detector | What it catches |
|
|
193
|
+
|----------|-----------------|
|
|
194
|
+
| **acl** | `public-read`, `public-read-write`, world-open grants |
|
|
195
|
+
| **policy** | Bucket policy statements wider than intent |
|
|
196
|
+
| **encryption** | Missing default encryption / SSE gaps |
|
|
197
|
+
| **logging** | No access logs on sensitive buckets |
|
|
198
|
+
| **versioning** | Versioning disabled on prod-like buckets |
|
|
199
|
+
| **lifecycle** | Aggressive expiration, incomplete multipart cleanup |
|
|
200
|
+
| **iam** | Over-broad SA roles, long-lived static keys |
|
|
201
|
+
| **chains** | Compound risk: public + no logs + no versioning + stale key |
|
|
202
|
+
|
|
203
|
+
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.
|
|
204
|
+
|
|
205
|
+
### Terraform drift
|
|
206
|
+
|
|
207
|
+
```bash
|
|
208
|
+
bucket-scanner diff examples/demo-vulnerable/terraform \
|
|
209
|
+
--fixture examples/demo-vulnerable/fixture.toml
|
|
210
|
+
|
|
211
|
+
bucket-scanner scan --folder-id b1g... --terraform ./infra/storage/
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
---
|
|
215
|
+
|
|
216
|
+
## Why not the console?
|
|
217
|
+
|
|
218
|
+
| | YC Console / manual checklist | Bucket Scanner |
|
|
219
|
+
|---|---|---|
|
|
220
|
+
| Scope | One bucket at a time | Whole folder · repeatable |
|
|
221
|
+
| Proof | ACL text says private | **`--probe` proves** anonymous reachability |
|
|
222
|
+
| Output | Screenshots in tickets | **Redacted** human / JSON / SARIF |
|
|
223
|
+
| Policy | Spreadsheet | `--fail-on high` · GitHub Action |
|
|
224
|
+
| Chains | Siloed findings | **Misconfig graphs** — why it hurts together |
|
|
225
|
+
| Drift | Point-in-time | CI on every PR · scheduled scans |
|
|
226
|
+
|
|
227
|
+
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?”
|
|
228
|
+
|
|
229
|
+
---
|
|
230
|
+
|
|
231
|
+
## CLI
|
|
232
|
+
|
|
233
|
+
```bash
|
|
234
|
+
bucket-scanner init [--force] [path] # write .bucket-scanner.toml
|
|
235
|
+
bucket-scanner doctor # creds, folder access, API health
|
|
236
|
+
bucket-scanner explain <rule-id> # remediation (e.g. acl/public-read)
|
|
237
|
+
bucket-scanner scan --folder-id ID # human report
|
|
238
|
+
bucket-scanner scan --folder-id ID --json # JSON to stdout
|
|
239
|
+
bucket-scanner scan --folder-id ID --sarif out.sarif --fail-on high
|
|
240
|
+
bucket-scanner scan --folder-id ID --baseline baselines/prod.json --fail-on new
|
|
241
|
+
bucket-scanner scan --folder-id ID --write-baseline baselines/prod.json
|
|
242
|
+
bucket-scanner scan --folder-id ID --probe # + anonymous reachability checks
|
|
243
|
+
bucket-scanner inspect BUCKET # single-bucket deep report
|
|
244
|
+
bucket-scanner chain --sa-id ID # blast radius from one SA
|
|
245
|
+
bucket-scanner diff PATH # Terraform vs live/fixture
|
|
246
|
+
bucket-scanner serve --addr 127.0.0.1:9090 # /metrics + /health
|
|
247
|
+
bucket-scanner list --folder-id ID # inventory summary
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
**Exit codes:** `0` clean / below threshold · `1` policy fail · `2` tool error.
|
|
251
|
+
|
|
252
|
+
Default `fail_on` in config is `high` (overridable via `--fail-on` or `.bucket-scanner.toml`).
|
|
253
|
+
|
|
254
|
+
---
|
|
255
|
+
|
|
256
|
+
## Configuration
|
|
257
|
+
|
|
258
|
+
`bucket-scanner init` writes `.bucket-scanner.toml`:
|
|
259
|
+
|
|
260
|
+
```toml
|
|
261
|
+
[scan]
|
|
262
|
+
folder_id = "b1gxxxxxxxxxx"
|
|
263
|
+
fail_on = "high"
|
|
264
|
+
probe = false
|
|
265
|
+
|
|
266
|
+
[scan.ignore_buckets]
|
|
267
|
+
names = ["public-assets-cdn"]
|
|
268
|
+
|
|
269
|
+
[[scan.severity_overrides]]
|
|
270
|
+
rule = "versioning/disabled"
|
|
271
|
+
severity = "medium"
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
See [docs/CONFIGURATION.md](docs/CONFIGURATION.md) for full reference.
|
|
275
|
+
|
|
276
|
+
---
|
|
277
|
+
|
|
278
|
+
## Architecture
|
|
279
|
+
|
|
280
|
+
```mermaid
|
|
281
|
+
flowchart LR
|
|
282
|
+
CLI["CLI<br/>scan · inspect · chain · doctor"] --> CFG[".bucket-scanner.toml"]
|
|
283
|
+
CFG --> SCAN["scan::run_scan"]
|
|
284
|
+
SCAN --> YC["YC Object Storage API<br/>metadata only"]
|
|
285
|
+
SCAN --> PROBE["probe::anonymous<br/>optional HEAD/list"]
|
|
286
|
+
YC --> DET["checks::*"]
|
|
287
|
+
PROBE --> DET
|
|
288
|
+
DET --> CHAIN["chains::compose"]
|
|
289
|
+
CHAIN --> OUT["report<br/>human · json · sarif"]
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
Details: [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) · [docs/CHECKS.md](docs/CHECKS.md)
|
|
293
|
+
|
|
294
|
+
---
|
|
295
|
+
|
|
296
|
+
## GitHub Actions
|
|
297
|
+
|
|
298
|
+
Minimal scan + SARIF upload. Full guide: [docs/GITHUB_ACTION.md](docs/GITHUB_ACTION.md).
|
|
299
|
+
|
|
300
|
+
```yaml
|
|
301
|
+
name: bucket-scanner
|
|
302
|
+
on:
|
|
303
|
+
pull_request:
|
|
304
|
+
push:
|
|
305
|
+
branches: [main]
|
|
306
|
+
schedule:
|
|
307
|
+
- cron: "0 6 * * *"
|
|
308
|
+
|
|
309
|
+
permissions:
|
|
310
|
+
contents: read
|
|
311
|
+
security-events: write
|
|
312
|
+
|
|
313
|
+
jobs:
|
|
314
|
+
scan:
|
|
315
|
+
runs-on: ubuntu-latest
|
|
316
|
+
steps:
|
|
317
|
+
- uses: actions/checkout@v4
|
|
318
|
+
- uses: actions/setup-python@v5
|
|
319
|
+
with:
|
|
320
|
+
python-version: "3.11"
|
|
321
|
+
- run: pip install .
|
|
322
|
+
- name: Scan YC folder
|
|
323
|
+
env:
|
|
324
|
+
YC_TOKEN: ${{ secrets.YC_TOKEN }}
|
|
325
|
+
YC_FOLDER_ID: ${{ secrets.YC_FOLDER_ID }}
|
|
326
|
+
run: |
|
|
327
|
+
bucket-scanner scan --folder-id "$YC_FOLDER_ID" \
|
|
328
|
+
--sarif bucket-scanner.sarif --fail-on high -q
|
|
329
|
+
- name: Upload SARIF
|
|
330
|
+
if: always()
|
|
331
|
+
uses: github/codeql-action/upload-sarif@v3
|
|
332
|
+
with:
|
|
333
|
+
sarif_file: bucket-scanner.sarif
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
---
|
|
337
|
+
|
|
338
|
+
## Security promises
|
|
339
|
+
|
|
340
|
+
- **Metadata by default** — list buckets, ACLs, policies, settings; no bulk object download.
|
|
341
|
+
- **Probe is opt-in** — anonymous HTTP checks only when you pass `--probe`.
|
|
342
|
+
- **Redaction** — SA key fragments, tokens, and sensitive URLs redacted in all report formats.
|
|
343
|
+
- **Offline fixtures** — `examples/demo-vulnerable/` uses clearly labeled **FAKE/EXAMPLE** values only.
|
|
344
|
+
|
|
345
|
+
See [SECURITY.md](SECURITY.md) and [docs/AUDIT.md](docs/AUDIT.md).
|
|
346
|
+
|
|
347
|
+
---
|
|
348
|
+
|
|
349
|
+
## Roadmap
|
|
350
|
+
|
|
351
|
+
- [x] Tracefuse hook — leaked `YC_*` in repo → cross-finding
|
|
352
|
+
- [x] Prometheus exporter + Grafana dashboard
|
|
353
|
+
- [x] Scheduled drift alerts (Telegram / webhook)
|
|
354
|
+
- [x] AWS S3 backend (optional second cloud)
|
|
355
|
+
- [x] Multi-region AWS inventory (per-bucket region resolution)
|
|
356
|
+
- [x] Scheduled scan profiles in config
|
|
357
|
+
- [x] CI/CD profile workflows (Action + scheduled matrix)
|
|
358
|
+
- [x] Baseline/delta + suppressions for production CI gates
|
|
359
|
+
- [x] Security hardening + audit docs (v0.11)
|
|
360
|
+
- [x] PyPI package (`pip install bucket-scanner`)
|
|
361
|
+
- [ ] Azure Blob live scan
|
|
362
|
+
- [ ] GCS backend
|
|
363
|
+
|
|
364
|
+
---
|
|
365
|
+
|
|
366
|
+
## License
|
|
367
|
+
|
|
368
|
+
MIT © FounderB — [LICENSE](LICENSE).
|
|
369
|
+
|
|
370
|
+
## Contributing
|
|
371
|
+
|
|
372
|
+
[CONTRIBUTING.md](CONTRIBUTING.md) · [CHANGELOG.md](CHANGELOG.md)
|