aiopsone-assure 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.
- aiopsone_assure-0.1.0/LICENSE +21 -0
- aiopsone_assure-0.1.0/PKG-INFO +122 -0
- aiopsone_assure-0.1.0/README.md +95 -0
- aiopsone_assure-0.1.0/aiopsone_assure.egg-info/PKG-INFO +122 -0
- aiopsone_assure-0.1.0/aiopsone_assure.egg-info/SOURCES.txt +21 -0
- aiopsone_assure-0.1.0/aiopsone_assure.egg-info/dependency_links.txt +1 -0
- aiopsone_assure-0.1.0/aiopsone_assure.egg-info/entry_points.txt +2 -0
- aiopsone_assure-0.1.0/aiopsone_assure.egg-info/requires.txt +9 -0
- aiopsone_assure-0.1.0/aiopsone_assure.egg-info/top_level.txt +1 -0
- aiopsone_assure-0.1.0/assure/__init__.py +6 -0
- aiopsone_assure-0.1.0/assure/cli.py +186 -0
- aiopsone_assure-0.1.0/assure/core/__init__.py +0 -0
- aiopsone_assure-0.1.0/assure/core/frameworks.py +108 -0
- aiopsone_assure-0.1.0/assure/core/ingest.py +160 -0
- aiopsone_assure-0.1.0/assure/core/mapping.py +75 -0
- aiopsone_assure-0.1.0/assure/core/narrate.py +81 -0
- aiopsone_assure-0.1.0/assure/core/report.py +248 -0
- aiopsone_assure-0.1.0/assure/core/scan.py +61 -0
- aiopsone_assure-0.1.0/assure/data/frameworks/cps230.json +407 -0
- aiopsone_assure-0.1.0/assure/data/frameworks/cps234.json +497 -0
- aiopsone_assure-0.1.0/pyproject.toml +44 -0
- aiopsone_assure-0.1.0/setup.cfg +4 -0
- aiopsone_assure-0.1.0/tests/test_assure.py +180 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Jayprakash Bilgaye
|
|
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,122 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: aiopsone-assure
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: APRA CPS 234 / CPS 230 AWS compliance evidence from your terminal — security findings to a board-ready narrative report.
|
|
5
|
+
Author: Jayprakash Bilgaye
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://aiopsone.com
|
|
8
|
+
Project-URL: Repository, https://github.com/jaybilgaye/aiopsone-assure
|
|
9
|
+
Project-URL: Issues, https://github.com/jaybilgaye/aiopsone-assure/issues
|
|
10
|
+
Keywords: apra,cps-234,cps-230,aws,compliance,prowler,cloud-security,bedrock,audit,governance,australia
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
|
+
Classifier: Environment :: Console
|
|
13
|
+
Classifier: Intended Audience :: Information Technology
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Topic :: Security
|
|
17
|
+
Requires-Python: >=3.9
|
|
18
|
+
Description-Content-Type: text/markdown
|
|
19
|
+
License-File: LICENSE
|
|
20
|
+
Provides-Extra: ai
|
|
21
|
+
Requires-Dist: boto3>=1.34.0; extra == "ai"
|
|
22
|
+
Provides-Extra: scan
|
|
23
|
+
Requires-Dist: prowler>=5.0.0; extra == "scan"
|
|
24
|
+
Provides-Extra: dev
|
|
25
|
+
Requires-Dist: pytest>=7.0; extra == "dev"
|
|
26
|
+
Dynamic: license-file
|
|
27
|
+
|
|
28
|
+
# aiopsone-assure
|
|
29
|
+
|
|
30
|
+
> **APRA compliance evidence for AWS, from your terminal.** Point `assure` at an AWS account (or existing Prowler findings) and get a **board-ready, APRA-paragraph-mapped narrative report** (Markdown + branded PDF) for **CPS 234** and **CPS 230** — generated locally, in your own environment.
|
|
31
|
+
|
|
32
|
+
[](LICENSE)
|
|
33
|
+
[](https://github.com/jaybilgaye/aiopsone-assure/actions/workflows/ci.yml)
|
|
34
|
+
|
|
35
|
+
**Keywords:** APRA CPS 234 / CPS 230 · AWS compliance report · Prowler findings to board narrative · Bedrock AI compliance · Australian regulated cloud
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## Why
|
|
40
|
+
|
|
41
|
+
Security scanners produce **findings**. Boards and APRA want **narrative evidence** — "demonstrate, mapped to CPS 234 ¶21, that information assets are encrypted, with evidence and a remediation plan." That translation is the biggest time-sink in an APRA review.
|
|
42
|
+
|
|
43
|
+
`assure` closes the gap: **findings → CPS 234/230 paragraph mapping → board-ready narrative report.** It runs entirely in your environment — your AWS credentials, your Bedrock, nothing leaves your account.
|
|
44
|
+
|
|
45
|
+
> Built on **Prowler**, **Powerpipe**, **Cloud Custodian** and **AWS Config** — the best open-source scanners. `assure` does the part they don't: turning their findings into APRA-paragraph board evidence.
|
|
46
|
+
|
|
47
|
+
## Install
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
pipx install aiopsone-assure # or: pip install aiopsone-assure
|
|
51
|
+
pipx install "aiopsone-assure[ai]" # + Bedrock AI narrative (boto3)
|
|
52
|
+
pipx install "aiopsone-assure[scan]" # + run Prowler scans (prowler)
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
PDF output needs Chrome/Chromium on the machine (set `$ASSURE_CHROME` to override the path), or use `--format md`.
|
|
56
|
+
|
|
57
|
+
## Usage
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
# 1. Run Prowler against an account and build the report in one step
|
|
61
|
+
assure scan --framework cps234 --region ap-southeast-2
|
|
62
|
+
|
|
63
|
+
# 2. Build a report from findings you already have (Prowler CSV / JSON / OCSF)
|
|
64
|
+
assure report --in findings.csv --framework cps234
|
|
65
|
+
|
|
66
|
+
# 3. Deterministic, no AI (template engine — default; zero AWS calls)
|
|
67
|
+
assure report --in findings.csv --no-ai
|
|
68
|
+
|
|
69
|
+
# 4. AI narrative via Amazon Bedrock (AU-resident), board-ready PDF
|
|
70
|
+
assure report --in findings.csv --engine bedrock --region ap-southeast-2 --format pdf
|
|
71
|
+
|
|
72
|
+
# 5. CI gate: non-zero exit if any control FAILs; machine-readable summary
|
|
73
|
+
assure report --in findings.csv --json
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
List bundled frameworks:
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
assure frameworks
|
|
80
|
+
# cps234 APRA CPS 234 Information Security (20 controls, 55 checks)
|
|
81
|
+
# cps230 APRA CPS 230 Operational Risk Management (18 controls, 15 checks)
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## What you get
|
|
85
|
+
|
|
86
|
+
A board-ready report with:
|
|
87
|
+
- **Executive summary** + automated compliance score
|
|
88
|
+
- **Control-by-control assessment** mapped to CPS 234/230 paragraphs (PASS / FAIL / MANUAL / NOT-ASSESSED)
|
|
89
|
+
- **Cited evidence** per failing control
|
|
90
|
+
- **Remediation roadmap**
|
|
91
|
+
|
|
92
|
+
Two formats: **Markdown** (always) and a **branded PDF** (professional, print-friendly).
|
|
93
|
+
|
|
94
|
+
## How it works
|
|
95
|
+
|
|
96
|
+
```
|
|
97
|
+
AWS account / existing findings
|
|
98
|
+
│ (your own AWS creds — nothing leaves your environment)
|
|
99
|
+
▼
|
|
100
|
+
assure ── run Prowler (scoped to the framework's checks)
|
|
101
|
+
│
|
|
102
|
+
├─ map check → CPS 234/230 paragraph (we own the mapping; no FW injection into Prowler)
|
|
103
|
+
├─ narrate: template (offline) or Amazon Bedrock / Claude (AU-resident)
|
|
104
|
+
▼
|
|
105
|
+
Board-ready report: Markdown + branded PDF
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## Exit codes
|
|
109
|
+
|
|
110
|
+
`0` no failing controls · `2` one or more controls FAIL (for CI gating) · `1` error. Use `--exit-zero` to always return 0.
|
|
111
|
+
|
|
112
|
+
## Frameworks are pluggable
|
|
113
|
+
|
|
114
|
+
A framework is just data — a pack JSON mapping checks → paragraphs. Bundled: CPS 234, CPS 230. Point `--framework path/to/pack.json` at your own. (Roadmap: Essential Eight, ACSC ISM/IRAP, then ISO 27001 / SOC 2.)
|
|
115
|
+
|
|
116
|
+
## Status & scope
|
|
117
|
+
|
|
118
|
+
v0.1 — CLI. Self-hosted, single-shot, stores nothing. The hosted SaaS (continuous, multi-account, managed AU-resident inference, dashboard) is a separate product that wraps this engine.
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
*Practitioner tooling for AWS Security in APRA-regulated Australia — [aiopsone.com](https://aiopsone.com). Not legal advice; verify against the official APRA standards.*
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# aiopsone-assure
|
|
2
|
+
|
|
3
|
+
> **APRA compliance evidence for AWS, from your terminal.** Point `assure` at an AWS account (or existing Prowler findings) and get a **board-ready, APRA-paragraph-mapped narrative report** (Markdown + branded PDF) for **CPS 234** and **CPS 230** — generated locally, in your own environment.
|
|
4
|
+
|
|
5
|
+
[](LICENSE)
|
|
6
|
+
[](https://github.com/jaybilgaye/aiopsone-assure/actions/workflows/ci.yml)
|
|
7
|
+
|
|
8
|
+
**Keywords:** APRA CPS 234 / CPS 230 · AWS compliance report · Prowler findings to board narrative · Bedrock AI compliance · Australian regulated cloud
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## Why
|
|
13
|
+
|
|
14
|
+
Security scanners produce **findings**. Boards and APRA want **narrative evidence** — "demonstrate, mapped to CPS 234 ¶21, that information assets are encrypted, with evidence and a remediation plan." That translation is the biggest time-sink in an APRA review.
|
|
15
|
+
|
|
16
|
+
`assure` closes the gap: **findings → CPS 234/230 paragraph mapping → board-ready narrative report.** It runs entirely in your environment — your AWS credentials, your Bedrock, nothing leaves your account.
|
|
17
|
+
|
|
18
|
+
> Built on **Prowler**, **Powerpipe**, **Cloud Custodian** and **AWS Config** — the best open-source scanners. `assure` does the part they don't: turning their findings into APRA-paragraph board evidence.
|
|
19
|
+
|
|
20
|
+
## Install
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
pipx install aiopsone-assure # or: pip install aiopsone-assure
|
|
24
|
+
pipx install "aiopsone-assure[ai]" # + Bedrock AI narrative (boto3)
|
|
25
|
+
pipx install "aiopsone-assure[scan]" # + run Prowler scans (prowler)
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
PDF output needs Chrome/Chromium on the machine (set `$ASSURE_CHROME` to override the path), or use `--format md`.
|
|
29
|
+
|
|
30
|
+
## Usage
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
# 1. Run Prowler against an account and build the report in one step
|
|
34
|
+
assure scan --framework cps234 --region ap-southeast-2
|
|
35
|
+
|
|
36
|
+
# 2. Build a report from findings you already have (Prowler CSV / JSON / OCSF)
|
|
37
|
+
assure report --in findings.csv --framework cps234
|
|
38
|
+
|
|
39
|
+
# 3. Deterministic, no AI (template engine — default; zero AWS calls)
|
|
40
|
+
assure report --in findings.csv --no-ai
|
|
41
|
+
|
|
42
|
+
# 4. AI narrative via Amazon Bedrock (AU-resident), board-ready PDF
|
|
43
|
+
assure report --in findings.csv --engine bedrock --region ap-southeast-2 --format pdf
|
|
44
|
+
|
|
45
|
+
# 5. CI gate: non-zero exit if any control FAILs; machine-readable summary
|
|
46
|
+
assure report --in findings.csv --json
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
List bundled frameworks:
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
assure frameworks
|
|
53
|
+
# cps234 APRA CPS 234 Information Security (20 controls, 55 checks)
|
|
54
|
+
# cps230 APRA CPS 230 Operational Risk Management (18 controls, 15 checks)
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## What you get
|
|
58
|
+
|
|
59
|
+
A board-ready report with:
|
|
60
|
+
- **Executive summary** + automated compliance score
|
|
61
|
+
- **Control-by-control assessment** mapped to CPS 234/230 paragraphs (PASS / FAIL / MANUAL / NOT-ASSESSED)
|
|
62
|
+
- **Cited evidence** per failing control
|
|
63
|
+
- **Remediation roadmap**
|
|
64
|
+
|
|
65
|
+
Two formats: **Markdown** (always) and a **branded PDF** (professional, print-friendly).
|
|
66
|
+
|
|
67
|
+
## How it works
|
|
68
|
+
|
|
69
|
+
```
|
|
70
|
+
AWS account / existing findings
|
|
71
|
+
│ (your own AWS creds — nothing leaves your environment)
|
|
72
|
+
▼
|
|
73
|
+
assure ── run Prowler (scoped to the framework's checks)
|
|
74
|
+
│
|
|
75
|
+
├─ map check → CPS 234/230 paragraph (we own the mapping; no FW injection into Prowler)
|
|
76
|
+
├─ narrate: template (offline) or Amazon Bedrock / Claude (AU-resident)
|
|
77
|
+
▼
|
|
78
|
+
Board-ready report: Markdown + branded PDF
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## Exit codes
|
|
82
|
+
|
|
83
|
+
`0` no failing controls · `2` one or more controls FAIL (for CI gating) · `1` error. Use `--exit-zero` to always return 0.
|
|
84
|
+
|
|
85
|
+
## Frameworks are pluggable
|
|
86
|
+
|
|
87
|
+
A framework is just data — a pack JSON mapping checks → paragraphs. Bundled: CPS 234, CPS 230. Point `--framework path/to/pack.json` at your own. (Roadmap: Essential Eight, ACSC ISM/IRAP, then ISO 27001 / SOC 2.)
|
|
88
|
+
|
|
89
|
+
## Status & scope
|
|
90
|
+
|
|
91
|
+
v0.1 — CLI. Self-hosted, single-shot, stores nothing. The hosted SaaS (continuous, multi-account, managed AU-resident inference, dashboard) is a separate product that wraps this engine.
|
|
92
|
+
|
|
93
|
+
---
|
|
94
|
+
|
|
95
|
+
*Practitioner tooling for AWS Security in APRA-regulated Australia — [aiopsone.com](https://aiopsone.com). Not legal advice; verify against the official APRA standards.*
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: aiopsone-assure
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: APRA CPS 234 / CPS 230 AWS compliance evidence from your terminal — security findings to a board-ready narrative report.
|
|
5
|
+
Author: Jayprakash Bilgaye
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://aiopsone.com
|
|
8
|
+
Project-URL: Repository, https://github.com/jaybilgaye/aiopsone-assure
|
|
9
|
+
Project-URL: Issues, https://github.com/jaybilgaye/aiopsone-assure/issues
|
|
10
|
+
Keywords: apra,cps-234,cps-230,aws,compliance,prowler,cloud-security,bedrock,audit,governance,australia
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
|
+
Classifier: Environment :: Console
|
|
13
|
+
Classifier: Intended Audience :: Information Technology
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Topic :: Security
|
|
17
|
+
Requires-Python: >=3.9
|
|
18
|
+
Description-Content-Type: text/markdown
|
|
19
|
+
License-File: LICENSE
|
|
20
|
+
Provides-Extra: ai
|
|
21
|
+
Requires-Dist: boto3>=1.34.0; extra == "ai"
|
|
22
|
+
Provides-Extra: scan
|
|
23
|
+
Requires-Dist: prowler>=5.0.0; extra == "scan"
|
|
24
|
+
Provides-Extra: dev
|
|
25
|
+
Requires-Dist: pytest>=7.0; extra == "dev"
|
|
26
|
+
Dynamic: license-file
|
|
27
|
+
|
|
28
|
+
# aiopsone-assure
|
|
29
|
+
|
|
30
|
+
> **APRA compliance evidence for AWS, from your terminal.** Point `assure` at an AWS account (or existing Prowler findings) and get a **board-ready, APRA-paragraph-mapped narrative report** (Markdown + branded PDF) for **CPS 234** and **CPS 230** — generated locally, in your own environment.
|
|
31
|
+
|
|
32
|
+
[](LICENSE)
|
|
33
|
+
[](https://github.com/jaybilgaye/aiopsone-assure/actions/workflows/ci.yml)
|
|
34
|
+
|
|
35
|
+
**Keywords:** APRA CPS 234 / CPS 230 · AWS compliance report · Prowler findings to board narrative · Bedrock AI compliance · Australian regulated cloud
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## Why
|
|
40
|
+
|
|
41
|
+
Security scanners produce **findings**. Boards and APRA want **narrative evidence** — "demonstrate, mapped to CPS 234 ¶21, that information assets are encrypted, with evidence and a remediation plan." That translation is the biggest time-sink in an APRA review.
|
|
42
|
+
|
|
43
|
+
`assure` closes the gap: **findings → CPS 234/230 paragraph mapping → board-ready narrative report.** It runs entirely in your environment — your AWS credentials, your Bedrock, nothing leaves your account.
|
|
44
|
+
|
|
45
|
+
> Built on **Prowler**, **Powerpipe**, **Cloud Custodian** and **AWS Config** — the best open-source scanners. `assure` does the part they don't: turning their findings into APRA-paragraph board evidence.
|
|
46
|
+
|
|
47
|
+
## Install
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
pipx install aiopsone-assure # or: pip install aiopsone-assure
|
|
51
|
+
pipx install "aiopsone-assure[ai]" # + Bedrock AI narrative (boto3)
|
|
52
|
+
pipx install "aiopsone-assure[scan]" # + run Prowler scans (prowler)
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
PDF output needs Chrome/Chromium on the machine (set `$ASSURE_CHROME` to override the path), or use `--format md`.
|
|
56
|
+
|
|
57
|
+
## Usage
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
# 1. Run Prowler against an account and build the report in one step
|
|
61
|
+
assure scan --framework cps234 --region ap-southeast-2
|
|
62
|
+
|
|
63
|
+
# 2. Build a report from findings you already have (Prowler CSV / JSON / OCSF)
|
|
64
|
+
assure report --in findings.csv --framework cps234
|
|
65
|
+
|
|
66
|
+
# 3. Deterministic, no AI (template engine — default; zero AWS calls)
|
|
67
|
+
assure report --in findings.csv --no-ai
|
|
68
|
+
|
|
69
|
+
# 4. AI narrative via Amazon Bedrock (AU-resident), board-ready PDF
|
|
70
|
+
assure report --in findings.csv --engine bedrock --region ap-southeast-2 --format pdf
|
|
71
|
+
|
|
72
|
+
# 5. CI gate: non-zero exit if any control FAILs; machine-readable summary
|
|
73
|
+
assure report --in findings.csv --json
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
List bundled frameworks:
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
assure frameworks
|
|
80
|
+
# cps234 APRA CPS 234 Information Security (20 controls, 55 checks)
|
|
81
|
+
# cps230 APRA CPS 230 Operational Risk Management (18 controls, 15 checks)
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## What you get
|
|
85
|
+
|
|
86
|
+
A board-ready report with:
|
|
87
|
+
- **Executive summary** + automated compliance score
|
|
88
|
+
- **Control-by-control assessment** mapped to CPS 234/230 paragraphs (PASS / FAIL / MANUAL / NOT-ASSESSED)
|
|
89
|
+
- **Cited evidence** per failing control
|
|
90
|
+
- **Remediation roadmap**
|
|
91
|
+
|
|
92
|
+
Two formats: **Markdown** (always) and a **branded PDF** (professional, print-friendly).
|
|
93
|
+
|
|
94
|
+
## How it works
|
|
95
|
+
|
|
96
|
+
```
|
|
97
|
+
AWS account / existing findings
|
|
98
|
+
│ (your own AWS creds — nothing leaves your environment)
|
|
99
|
+
▼
|
|
100
|
+
assure ── run Prowler (scoped to the framework's checks)
|
|
101
|
+
│
|
|
102
|
+
├─ map check → CPS 234/230 paragraph (we own the mapping; no FW injection into Prowler)
|
|
103
|
+
├─ narrate: template (offline) or Amazon Bedrock / Claude (AU-resident)
|
|
104
|
+
▼
|
|
105
|
+
Board-ready report: Markdown + branded PDF
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## Exit codes
|
|
109
|
+
|
|
110
|
+
`0` no failing controls · `2` one or more controls FAIL (for CI gating) · `1` error. Use `--exit-zero` to always return 0.
|
|
111
|
+
|
|
112
|
+
## Frameworks are pluggable
|
|
113
|
+
|
|
114
|
+
A framework is just data — a pack JSON mapping checks → paragraphs. Bundled: CPS 234, CPS 230. Point `--framework path/to/pack.json` at your own. (Roadmap: Essential Eight, ACSC ISM/IRAP, then ISO 27001 / SOC 2.)
|
|
115
|
+
|
|
116
|
+
## Status & scope
|
|
117
|
+
|
|
118
|
+
v0.1 — CLI. Self-hosted, single-shot, stores nothing. The hosted SaaS (continuous, multi-account, managed AU-resident inference, dashboard) is a separate product that wraps this engine.
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
*Practitioner tooling for AWS Security in APRA-regulated Australia — [aiopsone.com](https://aiopsone.com). Not legal advice; verify against the official APRA standards.*
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
LICENSE
|
|
2
|
+
README.md
|
|
3
|
+
pyproject.toml
|
|
4
|
+
aiopsone_assure.egg-info/PKG-INFO
|
|
5
|
+
aiopsone_assure.egg-info/SOURCES.txt
|
|
6
|
+
aiopsone_assure.egg-info/dependency_links.txt
|
|
7
|
+
aiopsone_assure.egg-info/entry_points.txt
|
|
8
|
+
aiopsone_assure.egg-info/requires.txt
|
|
9
|
+
aiopsone_assure.egg-info/top_level.txt
|
|
10
|
+
assure/__init__.py
|
|
11
|
+
assure/cli.py
|
|
12
|
+
assure/core/__init__.py
|
|
13
|
+
assure/core/frameworks.py
|
|
14
|
+
assure/core/ingest.py
|
|
15
|
+
assure/core/mapping.py
|
|
16
|
+
assure/core/narrate.py
|
|
17
|
+
assure/core/report.py
|
|
18
|
+
assure/core/scan.py
|
|
19
|
+
assure/data/frameworks/cps230.json
|
|
20
|
+
assure/data/frameworks/cps234.json
|
|
21
|
+
tests/test_assure.py
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
assure
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
"""assure — APRA compliance evidence for AWS, from your terminal.
|
|
2
|
+
|
|
3
|
+
assure scan --framework cps234 --region ap-southeast-2 # run Prowler, then report
|
|
4
|
+
assure report --in findings.csv --framework cps234 # report from existing findings
|
|
5
|
+
assure frameworks # list bundled frameworks
|
|
6
|
+
|
|
7
|
+
Exit codes: 0 = no failing controls · 2 = one or more controls FAIL · 1 = error
|
|
8
|
+
"""
|
|
9
|
+
import argparse
|
|
10
|
+
import json
|
|
11
|
+
import os
|
|
12
|
+
import shutil
|
|
13
|
+
import sys
|
|
14
|
+
|
|
15
|
+
from . import __version__
|
|
16
|
+
from .core import frameworks, ingest, mapping, narrate, report
|
|
17
|
+
|
|
18
|
+
# AU-resident inference profile (data residency for APRA-regulated entities), current model.
|
|
19
|
+
DEFAULT_MODEL = os.environ.get("BEDROCK_MODEL_ID", "au.anthropic.claude-sonnet-4-6")
|
|
20
|
+
DEFAULT_REGION = os.environ.get("AWS_REGION", "ap-southeast-2")
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def _err(msg):
|
|
24
|
+
print(f"assure: error: {msg}", file=sys.stderr)
|
|
25
|
+
return 1
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def _add_common(p):
|
|
29
|
+
p.add_argument("--framework", default="cps234",
|
|
30
|
+
help="framework alias (cps234, cps230) or path to a framework-pack .json")
|
|
31
|
+
p.add_argument("--engine", choices=["template", "bedrock"], default="template",
|
|
32
|
+
help="narrative engine (default: template / offline)")
|
|
33
|
+
p.add_argument("--no-ai", action="store_true", help="force the deterministic template engine")
|
|
34
|
+
p.add_argument("--model", default=DEFAULT_MODEL, help="Bedrock model id (with --engine bedrock)")
|
|
35
|
+
p.add_argument("--region", default=DEFAULT_REGION, help="AWS region")
|
|
36
|
+
p.add_argument("-o", "--output", default="assure-report",
|
|
37
|
+
help="output basename or path (default: assure-report)")
|
|
38
|
+
p.add_argument("--format", choices=["pdf", "md", "both"], default="both",
|
|
39
|
+
help="report format (default: both)")
|
|
40
|
+
p.add_argument("--json", action="store_true", help="print a machine-readable summary to stdout")
|
|
41
|
+
p.add_argument("--exit-zero", action="store_true", help="always exit 0, even with failing controls")
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def _outputs(base, fmt):
|
|
45
|
+
"""Resolve (md_path, pdf_path) honouring an explicit extension on base."""
|
|
46
|
+
root, ext = os.path.splitext(base)
|
|
47
|
+
if ext.lower() == ".md":
|
|
48
|
+
return root + ".md", root + ".pdf"
|
|
49
|
+
if ext.lower() == ".pdf":
|
|
50
|
+
return root + ".md", root + ".pdf"
|
|
51
|
+
return base + ".md", base + ".pdf"
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def _generate(fw, results, ctx, args):
|
|
55
|
+
ctx = dict(ctx)
|
|
56
|
+
ctx["engine"] = "template" if args.no_ai else args.engine
|
|
57
|
+
control_results = mapping.aggregate(fw, results)
|
|
58
|
+
s = mapping.summarise(control_results)
|
|
59
|
+
|
|
60
|
+
engine = "template" if args.no_ai else args.engine
|
|
61
|
+
try:
|
|
62
|
+
base_narrator = narrate.get_narrator(engine, args.model, args.region)
|
|
63
|
+
except RuntimeError as e:
|
|
64
|
+
return _err(str(e))
|
|
65
|
+
|
|
66
|
+
# Memoise per control so md + pdf reuse one narrative (no double Bedrock cost).
|
|
67
|
+
_cache = {}
|
|
68
|
+
|
|
69
|
+
def narrator(res):
|
|
70
|
+
if res.control.id not in _cache:
|
|
71
|
+
_cache[res.control.id] = base_narrator(res)
|
|
72
|
+
return _cache[res.control.id]
|
|
73
|
+
|
|
74
|
+
md = report.build_markdown(fw, control_results, ctx, narrator)
|
|
75
|
+
md_path, pdf_path = _outputs(args.output, args.format)
|
|
76
|
+
written = []
|
|
77
|
+
|
|
78
|
+
if args.format in ("md", "both"):
|
|
79
|
+
with open(md_path, "w", encoding="utf-8") as f:
|
|
80
|
+
f.write(md)
|
|
81
|
+
written.append(md_path)
|
|
82
|
+
|
|
83
|
+
if args.format in ("pdf", "both"):
|
|
84
|
+
# Re-narrate via HTML builder (same narrator) so AI text isn't regenerated twice
|
|
85
|
+
# for bedrock: build_html calls narrator again — acceptable for v1 (cache later).
|
|
86
|
+
html_doc = report.build_html(fw, control_results, ctx, narrator)
|
|
87
|
+
try:
|
|
88
|
+
report.render_pdf(html_doc, pdf_path)
|
|
89
|
+
written.append(pdf_path)
|
|
90
|
+
except report.PDFError as e:
|
|
91
|
+
if args.format == "pdf":
|
|
92
|
+
return _err(str(e))
|
|
93
|
+
print(f"assure: warning: PDF skipped ({e})", file=sys.stderr)
|
|
94
|
+
|
|
95
|
+
if args.json:
|
|
96
|
+
print(json.dumps({
|
|
97
|
+
"framework": fw.id, "score": s["score"], "counts": {
|
|
98
|
+
"fail": s["fail"], "pass": s["pass"], "manual": s["manual"],
|
|
99
|
+
"not_assessed": s["not_assessed"], "total": s["total"],
|
|
100
|
+
}, "outputs": written,
|
|
101
|
+
}, indent=2))
|
|
102
|
+
else:
|
|
103
|
+
print(f"✔ {fw.name}: {s['score']}% automated "
|
|
104
|
+
f"({s['pass']} pass · {s['fail']} fail · {s['manual']} manual"
|
|
105
|
+
+ (f" · {s['not_assessed']} not-assessed" if s['not_assessed'] else "") + ")")
|
|
106
|
+
for w in written:
|
|
107
|
+
print(f" → {w}")
|
|
108
|
+
|
|
109
|
+
if s["fail"] and not args.exit_zero:
|
|
110
|
+
return 2
|
|
111
|
+
return 0
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
def cmd_report(args):
|
|
115
|
+
try:
|
|
116
|
+
fw = frameworks.load(args.framework)
|
|
117
|
+
except frameworks.FrameworkError as e:
|
|
118
|
+
return _err(str(e))
|
|
119
|
+
if not os.path.exists(args.input):
|
|
120
|
+
return _err(f"findings file not found: {args.input}")
|
|
121
|
+
try:
|
|
122
|
+
results, ctx = ingest.load(args.input)
|
|
123
|
+
except ingest.IngestError as e:
|
|
124
|
+
return _err(str(e))
|
|
125
|
+
return _generate(fw, results, ctx, args)
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
def cmd_scan(args):
|
|
129
|
+
from .core import scan
|
|
130
|
+
try:
|
|
131
|
+
fw = frameworks.load(args.framework)
|
|
132
|
+
except frameworks.FrameworkError as e:
|
|
133
|
+
return _err(str(e))
|
|
134
|
+
print(f"Running Prowler for {fw.name} ({len(fw.check_index)} checks) in {args.region}…",
|
|
135
|
+
file=sys.stderr)
|
|
136
|
+
try:
|
|
137
|
+
csv_path, workdir = scan.run_prowler(fw, region=args.region, profile=args.profile)
|
|
138
|
+
except scan.ScanError as e:
|
|
139
|
+
return _err(str(e))
|
|
140
|
+
try:
|
|
141
|
+
results, ctx = ingest.load(csv_path)
|
|
142
|
+
finally:
|
|
143
|
+
shutil.rmtree(workdir, ignore_errors=True)
|
|
144
|
+
return _generate(fw, results, ctx, args)
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
def cmd_frameworks(args):
|
|
148
|
+
for name in frameworks.available():
|
|
149
|
+
fw = frameworks.load(name)
|
|
150
|
+
print(f"{name:10s} {fw.name} ({len(fw.controls)} controls, "
|
|
151
|
+
f"{len(fw.check_index)} checks)")
|
|
152
|
+
return 0
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
def build_parser():
|
|
156
|
+
p = argparse.ArgumentParser(prog="assure", description=__doc__,
|
|
157
|
+
formatter_class=argparse.RawDescriptionHelpFormatter)
|
|
158
|
+
p.add_argument("--version", action="version", version=f"assure {__version__}")
|
|
159
|
+
sub = p.add_subparsers(dest="command")
|
|
160
|
+
|
|
161
|
+
sp = sub.add_parser("scan", help="run Prowler against an AWS account, then build the report")
|
|
162
|
+
_add_common(sp)
|
|
163
|
+
sp.add_argument("--profile", default=None, help="AWS profile to use for the scan")
|
|
164
|
+
sp.set_defaults(func=cmd_scan)
|
|
165
|
+
|
|
166
|
+
rp = sub.add_parser("report", help="build the report from an existing findings file")
|
|
167
|
+
rp.add_argument("--in", dest="input", required=True, help="Prowler CSV/JSON findings file")
|
|
168
|
+
_add_common(rp)
|
|
169
|
+
rp.set_defaults(func=cmd_report)
|
|
170
|
+
|
|
171
|
+
fp = sub.add_parser("frameworks", help="list bundled frameworks")
|
|
172
|
+
fp.set_defaults(func=cmd_frameworks)
|
|
173
|
+
return p
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
def main(argv=None):
|
|
177
|
+
parser = build_parser()
|
|
178
|
+
args = parser.parse_args(argv)
|
|
179
|
+
if not getattr(args, "func", None):
|
|
180
|
+
parser.print_help()
|
|
181
|
+
return 0
|
|
182
|
+
return args.func(args)
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
if __name__ == "__main__":
|
|
186
|
+
sys.exit(main())
|
|
File without changes
|