open-aws-scanner 0.1.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.
- open_aws_scanner-0.1.0/PKG-INFO +609 -0
- open_aws_scanner-0.1.0/README.md +574 -0
- open_aws_scanner-0.1.0/open_aws_scanner/__init__.py +3 -0
- open_aws_scanner-0.1.0/open_aws_scanner/api.py +237 -0
- open_aws_scanner-0.1.0/open_aws_scanner/cli.py +163 -0
- open_aws_scanner-0.1.0/open_aws_scanner/database.py +46 -0
- open_aws_scanner-0.1.0/open_aws_scanner/scanner.py +604 -0
- open_aws_scanner-0.1.0/open_aws_scanner.egg-info/PKG-INFO +609 -0
- open_aws_scanner-0.1.0/open_aws_scanner.egg-info/SOURCES.txt +13 -0
- open_aws_scanner-0.1.0/open_aws_scanner.egg-info/dependency_links.txt +1 -0
- open_aws_scanner-0.1.0/open_aws_scanner.egg-info/entry_points.txt +2 -0
- open_aws_scanner-0.1.0/open_aws_scanner.egg-info/requires.txt +14 -0
- open_aws_scanner-0.1.0/open_aws_scanner.egg-info/top_level.txt +1 -0
- open_aws_scanner-0.1.0/pyproject.toml +51 -0
- open_aws_scanner-0.1.0/setup.cfg +4 -0
|
@@ -0,0 +1,609 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: open-aws-scanner
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Find unused AWS resources costing you money. No admin, no auth, just results.
|
|
5
|
+
Author: Jason
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/yourusername/open-aws-scanner
|
|
8
|
+
Project-URL: Issues, https://github.com/yourusername/open-aws-scanner/issues
|
|
9
|
+
Keywords: aws,cost-optimization,cloud,scanner,waste-detection
|
|
10
|
+
Classifier: Development Status :: 3 - Alpha
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: Intended Audience :: System Administrators
|
|
13
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
20
|
+
Classifier: Topic :: System :: Systems Administration
|
|
21
|
+
Requires-Python: >=3.9
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
Requires-Dist: fastapi>=0.100.0
|
|
24
|
+
Requires-Dist: uvicorn>=0.20.0
|
|
25
|
+
Requires-Dist: sqlalchemy>=2.0.0
|
|
26
|
+
Requires-Dist: apscheduler>=3.10.0
|
|
27
|
+
Requires-Dist: boto3>=1.28.0
|
|
28
|
+
Requires-Dist: python-dotenv>=1.0.0
|
|
29
|
+
Requires-Dist: slowapi>=0.1.9
|
|
30
|
+
Provides-Extra: postgres
|
|
31
|
+
Requires-Dist: psycopg2-binary>=2.9.0; extra == "postgres"
|
|
32
|
+
Provides-Extra: dev
|
|
33
|
+
Requires-Dist: pytest; extra == "dev"
|
|
34
|
+
Requires-Dist: httpx; extra == "dev"
|
|
35
|
+
|
|
36
|
+
# Open AWS Scanner
|
|
37
|
+
|
|
38
|
+
Find unused AWS resources costing you money. No admin panel, no Keycloak, no multi-tenant complexity — just point it at your AWS account and find waste.
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## Table of Contents
|
|
43
|
+
|
|
44
|
+
- [Install](#install)
|
|
45
|
+
- [How To: Run Your First Scan](#how-to-run-your-first-scan)
|
|
46
|
+
- [How To: Set Up AWS Credentials](#how-to-set-up-aws-credentials)
|
|
47
|
+
- [How To: Scan Multiple Regions](#how-to-scan-multiple-regions)
|
|
48
|
+
- [How To: Run as a Server](#how-to-run-as-a-server)
|
|
49
|
+
- [How To: Use the API](#how-to-use-the-api)
|
|
50
|
+
- [How To: Run with Docker](#how-to-run-with-docker)
|
|
51
|
+
- [How To: Use Stage Mode (No AWS Needed)](#how-to-use-stage-mode-no-aws-needed)
|
|
52
|
+
- [How To: Track Savings](#how-to-track-savings)
|
|
53
|
+
- [How To: Use Postgres Instead of SQLite](#how-to-use-postgres-instead-of-sqlite)
|
|
54
|
+
- [How To: Set Up the IAM Role](#how-to-set-up-the-iam-role)
|
|
55
|
+
- [How To: Verify Package Signatures](#how-to-verify-package-signatures)
|
|
56
|
+
- [CLI Reference](#cli-reference)
|
|
57
|
+
- [API Reference](#api-reference)
|
|
58
|
+
- [What It Scans](#what-it-scans)
|
|
59
|
+
- [Configuration Reference](#configuration-reference)
|
|
60
|
+
- [Relationship to CostOps Platform](#relationship-to-costops-platform)
|
|
61
|
+
- [License](#license)
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## Install
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
pip install open-aws-scanner
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Or from source:
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
git clone https://github.com/yourusername/open-aws-scanner.git
|
|
75
|
+
cd open-aws-scanner
|
|
76
|
+
pip install .
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
For development (editable install):
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
pip install -e .
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
|
|
87
|
+
## How To: Run Your First Scan
|
|
88
|
+
|
|
89
|
+
**Step 1** — Create a config file:
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
open-aws-scanner init
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
This creates `config.env` in your current directory.
|
|
96
|
+
|
|
97
|
+
**Step 2** — Edit `config.env` with your AWS setup (see [credentials section](#how-to-set-up-aws-credentials) below).
|
|
98
|
+
|
|
99
|
+
**Step 3** — Run a scan:
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
open-aws-scanner scan
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Output looks like:
|
|
106
|
+
|
|
107
|
+
```
|
|
108
|
+
================================================================================
|
|
109
|
+
Open AWS Scanner — 10 issues found | $472.90/mo potential savings
|
|
110
|
+
================================================================================
|
|
111
|
+
|
|
112
|
+
EC2_Instance (2 found, $227.50/mo)
|
|
113
|
+
• test-server-bob: CPU avg 2.1% over last 7 days $85.00/mo [us-east-1]
|
|
114
|
+
• legacy-worker-node: CPU avg 1.3% over last 7 days $142.50/mo [us-east-1]
|
|
115
|
+
|
|
116
|
+
EBS_Volume (2 found, $76.80/mo)
|
|
117
|
+
• backup-vol-old: Volume is not attached to any instance $64.00/mo [us-east-1]
|
|
118
|
+
• dev-data-volume: Volume is not attached to any instance $12.80/mo [us-east-1]
|
|
119
|
+
|
|
120
|
+
────────────────────────────────────────────────────────────────────────────────
|
|
121
|
+
Total potential savings: $472.90/month
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
**Step 4** — Get JSON output (for piping to other tools):
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
open-aws-scanner scan --output json > findings.json
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
---
|
|
131
|
+
|
|
132
|
+
## How To: Set Up AWS Credentials
|
|
133
|
+
|
|
134
|
+
The scanner needs read-only AWS access. Pick one of these methods:
|
|
135
|
+
|
|
136
|
+
### Option A: Use your existing AWS profile (simplest)
|
|
137
|
+
|
|
138
|
+
Leave `AWS_ROLE_ARN` blank in `config.env`. The scanner uses whatever credentials are available:
|
|
139
|
+
|
|
140
|
+
- `~/.aws/credentials` (AWS CLI profile)
|
|
141
|
+
- `AWS_ACCESS_KEY_ID` / `AWS_SECRET_ACCESS_KEY` environment variables
|
|
142
|
+
- EC2 instance profile or ECS task role
|
|
143
|
+
|
|
144
|
+
```env
|
|
145
|
+
AWS_ROLE_ARN=
|
|
146
|
+
AWS_REGIONS=us-east-1
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
### Option B: Assume an IAM role (cross-account)
|
|
150
|
+
|
|
151
|
+
Set up a read-only role in the target account (see [IAM setup](#how-to-set-up-the-iam-role)), then:
|
|
152
|
+
|
|
153
|
+
```env
|
|
154
|
+
AWS_ROLE_ARN=arn:aws:iam::123456789012:role/OpenScannerRole
|
|
155
|
+
AWS_EXTERNAL_ID=my-scanner
|
|
156
|
+
AWS_REGIONS=us-east-1
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
### Option C: Explicit credentials
|
|
160
|
+
|
|
161
|
+
```env
|
|
162
|
+
AWS_ACCESS_KEY_ID=AKIA...
|
|
163
|
+
AWS_SECRET_ACCESS_KEY=wJal...
|
|
164
|
+
AWS_REGIONS=us-east-1
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
Not recommended for production — use roles or profiles instead.
|
|
168
|
+
|
|
169
|
+
### Verify credentials work
|
|
170
|
+
|
|
171
|
+
```bash
|
|
172
|
+
# Quick check that your credentials are valid
|
|
173
|
+
aws sts get-caller-identity
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
---
|
|
177
|
+
|
|
178
|
+
## How To: Scan Multiple Regions
|
|
179
|
+
|
|
180
|
+
Comma-separate regions in `config.env`:
|
|
181
|
+
|
|
182
|
+
```env
|
|
183
|
+
AWS_REGIONS=us-east-1,us-west-2,eu-west-1,ap-southeast-1
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
Or override from CLI:
|
|
187
|
+
|
|
188
|
+
```bash
|
|
189
|
+
open-aws-scanner scan --regions us-east-1,eu-west-1
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
Each region is scanned independently. Findings are tagged with their region.
|
|
193
|
+
|
|
194
|
+
---
|
|
195
|
+
|
|
196
|
+
## How To: Run as a Server
|
|
197
|
+
|
|
198
|
+
Start the API server with automatic scheduled scans:
|
|
199
|
+
|
|
200
|
+
```bash
|
|
201
|
+
open-aws-scanner serve
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
This gives you:
|
|
205
|
+
|
|
206
|
+
- Automatic scans every N hours (default: 6, configurable via `SCAN_INTERVAL_HOURS`)
|
|
207
|
+
- REST API for querying findings
|
|
208
|
+
- JSON index page at `/` with status summary
|
|
209
|
+
- Swagger docs at `/docs`
|
|
210
|
+
|
|
211
|
+
Custom host/port:
|
|
212
|
+
|
|
213
|
+
```bash
|
|
214
|
+
open-aws-scanner serve --host 127.0.0.1 --port 9000
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
Keep it running in the background:
|
|
218
|
+
|
|
219
|
+
```bash
|
|
220
|
+
nohup open-aws-scanner serve > scanner.log 2>&1 &
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
Or with systemd (Linux):
|
|
224
|
+
|
|
225
|
+
```ini
|
|
226
|
+
# /etc/systemd/system/open-aws-scanner.service
|
|
227
|
+
[Unit]
|
|
228
|
+
Description=Open AWS Scanner
|
|
229
|
+
After=network.target
|
|
230
|
+
|
|
231
|
+
[Service]
|
|
232
|
+
Type=simple
|
|
233
|
+
WorkingDirectory=/opt/scanner
|
|
234
|
+
ExecStart=/usr/local/bin/open-aws-scanner serve
|
|
235
|
+
Restart=always
|
|
236
|
+
Environment=AWS_REGIONS=us-east-1
|
|
237
|
+
|
|
238
|
+
[Install]
|
|
239
|
+
WantedBy=multi-user.target
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
---
|
|
243
|
+
|
|
244
|
+
## How To: Use the API
|
|
245
|
+
|
|
246
|
+
Once the server is running:
|
|
247
|
+
|
|
248
|
+
### Trigger a scan
|
|
249
|
+
|
|
250
|
+
```bash
|
|
251
|
+
curl -X POST http://localhost:8000/scan
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
### Get all findings
|
|
255
|
+
|
|
256
|
+
```bash
|
|
257
|
+
curl http://localhost:8000/findings
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
### Filter findings
|
|
261
|
+
|
|
262
|
+
```bash
|
|
263
|
+
# Only open findings
|
|
264
|
+
curl "http://localhost:8000/findings?status=open"
|
|
265
|
+
|
|
266
|
+
# Only EC2 findings
|
|
267
|
+
curl "http://localhost:8000/findings?resource_type=EC2_Instance"
|
|
268
|
+
|
|
269
|
+
# Combine filters
|
|
270
|
+
curl "http://localhost:8000/findings?status=open&resource_type=EBS_Volume"
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
### Mark a finding as fixed
|
|
274
|
+
|
|
275
|
+
```bash
|
|
276
|
+
curl -X PUT "http://localhost:8000/findings/42/status?status=fixed"
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
Valid statuses: `open`, `fixed`, `dismissed`, `in_progress`
|
|
280
|
+
|
|
281
|
+
### Get savings summary
|
|
282
|
+
|
|
283
|
+
```bash
|
|
284
|
+
curl http://localhost:8000/summary
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
Response:
|
|
288
|
+
|
|
289
|
+
```json
|
|
290
|
+
{
|
|
291
|
+
"total_findings": 10,
|
|
292
|
+
"total_potential_savings": 472.90,
|
|
293
|
+
"open": { "count": 7, "savings": 380.50 },
|
|
294
|
+
"fixed": { "count": 2, "savings_realized": 67.65 },
|
|
295
|
+
"dismissed": { "count": 0, "savings": 0 },
|
|
296
|
+
"in_progress": { "count": 1, "savings": 24.75 }
|
|
297
|
+
}
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
### Get scan history
|
|
301
|
+
|
|
302
|
+
```bash
|
|
303
|
+
curl http://localhost:8000/scans
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
---
|
|
307
|
+
|
|
308
|
+
## How To: Run with Docker
|
|
309
|
+
|
|
310
|
+
### Build and run
|
|
311
|
+
|
|
312
|
+
```bash
|
|
313
|
+
docker build -t open-aws-scanner .
|
|
314
|
+
docker run -p 8000:8000 --env-file config.env open-aws-scanner
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
### With AWS credentials from host
|
|
318
|
+
|
|
319
|
+
```bash
|
|
320
|
+
docker run -p 8000:8000 \
|
|
321
|
+
-e AWS_REGIONS=us-east-1 \
|
|
322
|
+
-e STAGE_MODE=true \
|
|
323
|
+
-v ~/.aws:/root/.aws:ro \
|
|
324
|
+
open-aws-scanner
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
### Persist the database
|
|
328
|
+
|
|
329
|
+
```bash
|
|
330
|
+
docker run -p 8000:8000 \
|
|
331
|
+
--env-file config.env \
|
|
332
|
+
-v $(pwd)/data:/app/scanner.db \
|
|
333
|
+
open-aws-scanner
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
---
|
|
337
|
+
|
|
338
|
+
## How To: Use Stage Mode (No AWS Needed)
|
|
339
|
+
|
|
340
|
+
Stage mode uses mock data — no real AWS credentials required. Perfect for:
|
|
341
|
+
|
|
342
|
+
- Testing the API
|
|
343
|
+
- Developing integrations
|
|
344
|
+
- Demoing the tool
|
|
345
|
+
|
|
346
|
+
Set in `config.env`:
|
|
347
|
+
|
|
348
|
+
```env
|
|
349
|
+
STAGE_MODE=true
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
Or as an environment variable:
|
|
353
|
+
|
|
354
|
+
```bash
|
|
355
|
+
STAGE_MODE=true open-aws-scanner scan
|
|
356
|
+
STAGE_MODE=true open-aws-scanner serve
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
---
|
|
360
|
+
|
|
361
|
+
## How To: Track Savings
|
|
362
|
+
|
|
363
|
+
The scanner tracks finding status over time. A typical workflow:
|
|
364
|
+
|
|
365
|
+
1. Run a scan → findings are `open`
|
|
366
|
+
2. Fix a resource (e.g., delete the unused EBS volume in AWS console)
|
|
367
|
+
3. Mark it fixed:
|
|
368
|
+
|
|
369
|
+
```bash
|
|
370
|
+
curl -X PUT "http://localhost:8000/findings/42/status?status=fixed"
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
4. Check realized savings:
|
|
374
|
+
|
|
375
|
+
```bash
|
|
376
|
+
curl http://localhost:8000/summary
|
|
377
|
+
# → "fixed": { "count": 3, "savings_realized": 145.25 }
|
|
378
|
+
```
|
|
379
|
+
|
|
380
|
+
Statuses:
|
|
381
|
+
|
|
382
|
+
| Status | Meaning |
|
|
383
|
+
|--------|---------|
|
|
384
|
+
| `open` | Identified waste, not yet addressed |
|
|
385
|
+
| `in_progress` | Being worked on |
|
|
386
|
+
| `fixed` | Resource cleaned up — savings realized |
|
|
387
|
+
| `dismissed` | Intentionally kept (not waste) |
|
|
388
|
+
|
|
389
|
+
---
|
|
390
|
+
|
|
391
|
+
## How To: Use Postgres Instead of SQLite
|
|
392
|
+
|
|
393
|
+
By default the scanner uses SQLite (zero config, file-based). For production or team use, switch to Postgres:
|
|
394
|
+
|
|
395
|
+
**Step 1** — Install the postgres extra:
|
|
396
|
+
|
|
397
|
+
```bash
|
|
398
|
+
pip install open-aws-scanner[postgres]
|
|
399
|
+
```
|
|
400
|
+
|
|
401
|
+
**Step 2** — Set `DATABASE_URL` in `config.env`:
|
|
402
|
+
|
|
403
|
+
```env
|
|
404
|
+
DATABASE_URL=postgresql://user:pass@localhost:5432/scanner
|
|
405
|
+
```
|
|
406
|
+
|
|
407
|
+
**Step 3** — Create the database:
|
|
408
|
+
|
|
409
|
+
```bash
|
|
410
|
+
createdb scanner
|
|
411
|
+
```
|
|
412
|
+
|
|
413
|
+
The tables are created automatically on first run.
|
|
414
|
+
|
|
415
|
+
---
|
|
416
|
+
|
|
417
|
+
## How To: Set Up the IAM Role
|
|
418
|
+
|
|
419
|
+
If scanning a different AWS account, create a read-only role:
|
|
420
|
+
|
|
421
|
+
**Step 1** — In the target account, create a role with this trust policy:
|
|
422
|
+
|
|
423
|
+
```json
|
|
424
|
+
{
|
|
425
|
+
"Version": "2012-10-17",
|
|
426
|
+
"Statement": [
|
|
427
|
+
{
|
|
428
|
+
"Effect": "Allow",
|
|
429
|
+
"Principal": {
|
|
430
|
+
"AWS": "arn:aws:iam::YOUR_SCANNER_ACCOUNT:root"
|
|
431
|
+
},
|
|
432
|
+
"Action": "sts:AssumeRole",
|
|
433
|
+
"Condition": {
|
|
434
|
+
"StringEquals": {
|
|
435
|
+
"sts:ExternalId": "my-scanner"
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
]
|
|
440
|
+
}
|
|
441
|
+
```
|
|
442
|
+
|
|
443
|
+
**Step 2** — Attach this permissions policy to the role:
|
|
444
|
+
|
|
445
|
+
```json
|
|
446
|
+
{
|
|
447
|
+
"Version": "2012-10-17",
|
|
448
|
+
"Statement": [
|
|
449
|
+
{
|
|
450
|
+
"Effect": "Allow",
|
|
451
|
+
"Action": [
|
|
452
|
+
"ec2:Describe*",
|
|
453
|
+
"rds:DescribeDBInstances",
|
|
454
|
+
"lambda:ListFunctions",
|
|
455
|
+
"s3:ListAllMyBuckets",
|
|
456
|
+
"s3:ListBucket",
|
|
457
|
+
"sqs:ListQueues",
|
|
458
|
+
"sns:ListTopics",
|
|
459
|
+
"elasticloadbalancing:DescribeLoadBalancers",
|
|
460
|
+
"dynamodb:ListTables",
|
|
461
|
+
"elasticache:DescribeCacheClusters",
|
|
462
|
+
"logs:DescribeLogGroups",
|
|
463
|
+
"logs:DescribeLogStreams",
|
|
464
|
+
"secretsmanager:ListSecrets",
|
|
465
|
+
"cloudwatch:GetMetricStatistics"
|
|
466
|
+
],
|
|
467
|
+
"Resource": "*"
|
|
468
|
+
}
|
|
469
|
+
]
|
|
470
|
+
}
|
|
471
|
+
```
|
|
472
|
+
|
|
473
|
+
**Step 3** — Configure `config.env`:
|
|
474
|
+
|
|
475
|
+
```env
|
|
476
|
+
AWS_ROLE_ARN=arn:aws:iam::123456789012:role/OpenScannerRole
|
|
477
|
+
AWS_EXTERNAL_ID=my-scanner
|
|
478
|
+
```
|
|
479
|
+
|
|
480
|
+
**Step 4** — Make sure the machine running the scanner has `sts:AssumeRole` permission for that role ARN.
|
|
481
|
+
|
|
482
|
+
---
|
|
483
|
+
|
|
484
|
+
## How To: Verify Package Signatures
|
|
485
|
+
|
|
486
|
+
All releases are signed with [Sigstore](https://www.sigstore.dev/).
|
|
487
|
+
|
|
488
|
+
### Verify a release
|
|
489
|
+
|
|
490
|
+
```bash
|
|
491
|
+
pip install sigstore
|
|
492
|
+
|
|
493
|
+
sigstore verify identity open_aws_scanner-0.1.0.tar.gz \
|
|
494
|
+
--cert-identity "luge-sud-0q@icloud.com" \
|
|
495
|
+
--cert-oidc-issuer "https://appleid.apple.com"
|
|
496
|
+
```
|
|
497
|
+
|
|
498
|
+
### Verify git commits
|
|
499
|
+
|
|
500
|
+
```bash
|
|
501
|
+
git log --show-signature
|
|
502
|
+
```
|
|
503
|
+
|
|
504
|
+
---
|
|
505
|
+
|
|
506
|
+
## CLI Reference
|
|
507
|
+
|
|
508
|
+
```
|
|
509
|
+
open-aws-scanner init
|
|
510
|
+
Create a config.env template in the current directory.
|
|
511
|
+
|
|
512
|
+
open-aws-scanner scan [OPTIONS]
|
|
513
|
+
Run a one-shot scan and print results.
|
|
514
|
+
|
|
515
|
+
--regions REGIONS Comma-separated AWS regions (overrides config)
|
|
516
|
+
--role-arn ARN AWS role ARN to assume (overrides config)
|
|
517
|
+
--output {json,table} Output format (default: table)
|
|
518
|
+
--config PATH Path to config.env (default: ./config.env)
|
|
519
|
+
|
|
520
|
+
open-aws-scanner serve [OPTIONS]
|
|
521
|
+
Start the API server with scheduled scans.
|
|
522
|
+
|
|
523
|
+
--host HOST Host to bind (default: 0.0.0.0)
|
|
524
|
+
--port PORT Port to bind (default: 8000)
|
|
525
|
+
--config PATH Path to config.env (default: ./config.env)
|
|
526
|
+
```
|
|
527
|
+
|
|
528
|
+
---
|
|
529
|
+
|
|
530
|
+
## API Reference
|
|
531
|
+
|
|
532
|
+
| Method | Endpoint | Description |
|
|
533
|
+
|--------|----------|-------------|
|
|
534
|
+
| GET | `/` | Status summary + endpoint list (JSON) |
|
|
535
|
+
| GET | `/health` | Health check |
|
|
536
|
+
| POST | `/scan` | Trigger a scan now |
|
|
537
|
+
| GET | `/findings` | List all findings |
|
|
538
|
+
| GET | `/findings?status=open` | Filter by status |
|
|
539
|
+
| GET | `/findings?resource_type=EC2_Instance` | Filter by resource type |
|
|
540
|
+
| PUT | `/findings/{id}/status?status=fixed` | Update finding status |
|
|
541
|
+
| GET | `/summary` | Savings summary by status |
|
|
542
|
+
| GET | `/scans` | Scan run history |
|
|
543
|
+
| GET | `/docs` | Swagger UI (interactive) |
|
|
544
|
+
| GET | `/redoc` | ReDoc (readable docs) |
|
|
545
|
+
|
|
546
|
+
---
|
|
547
|
+
|
|
548
|
+
## What It Scans
|
|
549
|
+
|
|
550
|
+
| Resource | Detection | Est. Savings |
|
|
551
|
+
|----------|-----------|-------------|
|
|
552
|
+
| EBS Volumes | Unattached | $0.08/GB/mo |
|
|
553
|
+
| Elastic IPs | Unassociated | $3.65/mo |
|
|
554
|
+
| EBS Snapshots | Orphaned (source volume deleted, 30+ days) | $0.05/GB/mo |
|
|
555
|
+
| ENIs | Detached | $0 |
|
|
556
|
+
| Security Groups | Not attached to any ENI | $0 |
|
|
557
|
+
| EC2 Instances | CPU avg < 5% over 7 days | — |
|
|
558
|
+
| RDS Instances | < 1 avg connection over 7 days | — |
|
|
559
|
+
| Lambda Functions | Zero invocations in 30 days | $0 |
|
|
560
|
+
| S3 Buckets | Empty (zero objects) | $0 |
|
|
561
|
+
| SQS Queues | Zero messages sent in 14 days | $0 |
|
|
562
|
+
| SNS Topics | Zero publishes in 14 days | $0 |
|
|
563
|
+
| Load Balancers | Zero requests in 7 days | $16.20/mo |
|
|
564
|
+
| NAT Gateways | Zero bytes processed in 7 days | $32.40/mo |
|
|
565
|
+
| DynamoDB Tables | Zero read capacity in 14 days | — |
|
|
566
|
+
| ElastiCache | < 1 avg connection in 7 days | — |
|
|
567
|
+
| CloudWatch Logs | No ingestion in 30 days | $0.03/GB |
|
|
568
|
+
| Secrets Manager | Not accessed in 90 days | $0.40/mo |
|
|
569
|
+
|
|
570
|
+
---
|
|
571
|
+
|
|
572
|
+
## Configuration Reference
|
|
573
|
+
|
|
574
|
+
All settings go in `config.env` (or as environment variables):
|
|
575
|
+
|
|
576
|
+
| Variable | Description | Default |
|
|
577
|
+
|----------|-------------|---------|
|
|
578
|
+
| `AWS_ROLE_ARN` | IAM role to assume (blank = use local creds) | *(empty)* |
|
|
579
|
+
| `AWS_EXTERNAL_ID` | External ID for role assumption | *(empty)* |
|
|
580
|
+
| `AWS_REGIONS` | Comma-separated regions to scan | `us-east-1` |
|
|
581
|
+
| `AWS_ACCESS_KEY_ID` | Explicit access key (optional) | *(from env/profile)* |
|
|
582
|
+
| `AWS_SECRET_ACCESS_KEY` | Explicit secret key (optional) | *(from env/profile)* |
|
|
583
|
+
| `SCAN_INTERVAL_HOURS` | Hours between scheduled scans (server mode) | `6` |
|
|
584
|
+
| `STAGE_MODE` | Use mock data (no real AWS calls) | `false` |
|
|
585
|
+
| `DATABASE_URL` | Database connection string | `sqlite:///./scanner.db` |
|
|
586
|
+
| `HOST` | Server bind host | `0.0.0.0` |
|
|
587
|
+
| `PORT` | Server bind port | `8000` |
|
|
588
|
+
|
|
589
|
+
---
|
|
590
|
+
|
|
591
|
+
## Relationship to CostOps Platform
|
|
592
|
+
|
|
593
|
+
This is the open-source core of the [CostOps AWS Scanner](../costops-AWS-scanner/) platform. The full platform adds:
|
|
594
|
+
|
|
595
|
+
- Multi-tenant support with per-tenant IAM role assumption
|
|
596
|
+
- Keycloak SSO with JWT zero-trust auth on every endpoint
|
|
597
|
+
- Admin API for tenant/user/billing management
|
|
598
|
+
- React dashboard with drag-and-drop tiles
|
|
599
|
+
- AWS Cost Explorer integration (rightsizing, RI/Savings Plans utilization)
|
|
600
|
+
- Email reports, activity logging, billing model
|
|
601
|
+
- 55+ resource scanners (this package has the core 17)
|
|
602
|
+
|
|
603
|
+
The full scanner imports scanning functions from this package — one codebase, shared logic.
|
|
604
|
+
|
|
605
|
+
---
|
|
606
|
+
|
|
607
|
+
## License
|
|
608
|
+
|
|
609
|
+
MIT
|