cloudg 0.3.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.
Files changed (85) hide show
  1. cloudg-0.3.0/.gitignore +69 -0
  2. cloudg-0.3.0/LICENSE +21 -0
  3. cloudg-0.3.0/PKG-INFO +330 -0
  4. cloudg-0.3.0/README.md +260 -0
  5. cloudg-0.3.0/cloudg/__init__.py +21 -0
  6. cloudg-0.3.0/cloudg/api.py +613 -0
  7. cloudg-0.3.0/cloudg/cli.py +934 -0
  8. cloudg-0.3.0/cloudg/collectors/__init__.py +5 -0
  9. cloudg-0.3.0/cloudg/collectors/aws.py +830 -0
  10. cloudg-0.3.0/cloudg/collectors/azure.py +362 -0
  11. cloudg-0.3.0/cloudg/collectors/base.py +44 -0
  12. cloudg-0.3.0/cloudg/collectors/gcp.py +170 -0
  13. cloudg-0.3.0/cloudg/collectors/multi.py +329 -0
  14. cloudg-0.3.0/cloudg/config.py +261 -0
  15. cloudg-0.3.0/cloudg/coverage.py +93 -0
  16. cloudg-0.3.0/cloudg/credentials.py +451 -0
  17. cloudg-0.3.0/cloudg/graph/__init__.py +6 -0
  18. cloudg-0.3.0/cloudg/graph/builder.py +336 -0
  19. cloudg-0.3.0/cloudg/graph/ontology.py +914 -0
  20. cloudg-0.3.0/cloudg/graph/rag_export.py +533 -0
  21. cloudg-0.3.0/cloudg/graph/reachability.py +237 -0
  22. cloudg-0.3.0/cloudg/normaliser.py +390 -0
  23. cloudg-0.3.0/cloudg/policies/custodian-aws-security.yml +139 -0
  24. cloudg-0.3.0/cloudg/policies/custodian-azure.yml +95 -0
  25. cloudg-0.3.0/cloudg/policies/custodian-gcp.yml +87 -0
  26. cloudg-0.3.0/cloudg/policies/custodian.yml +131 -0
  27. cloudg-0.3.0/cloudg/region_discovery.py +330 -0
  28. cloudg-0.3.0/cloudg/registry.py +142 -0
  29. cloudg-0.3.0/cloudg/renderers/__init__.py +1 -0
  30. cloudg-0.3.0/cloudg/renderers/html_report.py +430 -0
  31. cloudg-0.3.0/cloudg/renderers/json_export.py +65 -0
  32. cloudg-0.3.0/cloudg/renderers/svg.py +689 -0
  33. cloudg-0.3.0/cloudg/renderers/terraform_export.py +666 -0
  34. cloudg-0.3.0/cloudg/retry.py +103 -0
  35. cloudg-0.3.0/cloudg/rules/cis_aws_v3.yaml +148 -0
  36. cloudg-0.3.0/cloudg/rules/cis_azure_v2.yaml +142 -0
  37. cloudg-0.3.0/cloudg/rules/cis_gcp_v3.yaml +133 -0
  38. cloudg-0.3.0/cloudg/rules/frameworks/aws_foundational_security_best_practices_aws.yaml +1286 -0
  39. cloudg-0.3.0/cloudg/rules/frameworks/cis_5.0_aws.yaml +280 -0
  40. cloudg-0.3.0/cloudg/rules/frameworks/cis_5.0_azure.yaml +475 -0
  41. cloudg-0.3.0/cloudg/rules/frameworks/cis_5.0_gcp.yaml +327 -0
  42. cloudg-0.3.0/cloudg/rules/frameworks/gdpr_aws.yaml +95 -0
  43. cloudg-0.3.0/cloudg/rules/frameworks/hipaa_aws.yaml +461 -0
  44. cloudg-0.3.0/cloudg/rules/frameworks/hipaa_azure.yaml +504 -0
  45. cloudg-0.3.0/cloudg/rules/frameworks/hipaa_gcp.yaml +211 -0
  46. cloudg-0.3.0/cloudg/rules/frameworks/iso27001_2022_aws.yaml +789 -0
  47. cloudg-0.3.0/cloudg/rules/frameworks/iso27001_2022_azure.yaml +477 -0
  48. cloudg-0.3.0/cloudg/rules/frameworks/iso27001_2022_gcp.yaml +240 -0
  49. cloudg-0.3.0/cloudg/rules/frameworks/mitre_attack_aws.yaml +596 -0
  50. cloudg-0.3.0/cloudg/rules/frameworks/mitre_attack_azure.yaml +418 -0
  51. cloudg-0.3.0/cloudg/rules/frameworks/mitre_attack_gcp.yaml +300 -0
  52. cloudg-0.3.0/cloudg/rules/frameworks/nist_800_53_revision_5_aws.yaml +3234 -0
  53. cloudg-0.3.0/cloudg/rules/frameworks/nist_csf_2.0_aws.yaml +828 -0
  54. cloudg-0.3.0/cloudg/rules/frameworks/pci_4.0_aws.yaml +7108 -0
  55. cloudg-0.3.0/cloudg/rules/frameworks/pci_4.0_azure.yaml +4696 -0
  56. cloudg-0.3.0/cloudg/rules/frameworks/pci_4.0_gcp.yaml +5405 -0
  57. cloudg-0.3.0/cloudg/rules/frameworks/soc2_aws.yaml +421 -0
  58. cloudg-0.3.0/cloudg/rules/frameworks/soc2_azure.yaml +477 -0
  59. cloudg-0.3.0/cloudg/rules/frameworks/soc2_gcp.yaml +342 -0
  60. cloudg-0.3.0/cloudg/rules/gdpr.yaml +56 -0
  61. cloudg-0.3.0/cloudg/rules/hipaa_security_rule.yaml +83 -0
  62. cloudg-0.3.0/cloudg/rules/iso_27001_2022.yaml +88 -0
  63. cloudg-0.3.0/cloudg/rules/nist_800_53.yaml +134 -0
  64. cloudg-0.3.0/cloudg/rules/pci_dss_v4.yaml +108 -0
  65. cloudg-0.3.0/cloudg/rules/soc2_tsc.yaml +93 -0
  66. cloudg-0.3.0/cloudg/scanners/__init__.py +1 -0
  67. cloudg-0.3.0/cloudg/scanners/checkov.py +174 -0
  68. cloudg-0.3.0/cloudg/scanners/iam_linter.py +200 -0
  69. cloudg-0.3.0/cloudg/scanners/prowler.py +237 -0
  70. cloudg-0.3.0/cloudg/scanners/scoutsuite.py +163 -0
  71. cloudg-0.3.0/cloudg/scanners/trivy.py +339 -0
  72. cloudg-0.3.0/cloudg/schema/__init__.py +25 -0
  73. cloudg-0.3.0/cloudg/schema/models.py +260 -0
  74. cloudg-0.3.0/cloudg/templates/report.html.j2 +828 -0
  75. cloudg-0.3.0/pyproject.toml +112 -0
  76. cloudg-0.3.0/tests/__init__.py +0 -0
  77. cloudg-0.3.0/tests/conftest.py +56 -0
  78. cloudg-0.3.0/tests/test_api.py +149 -0
  79. cloudg-0.3.0/tests/test_collectors.py +329 -0
  80. cloudg-0.3.0/tests/test_normaliser.py +327 -0
  81. cloudg-0.3.0/tests/test_ontology.py +389 -0
  82. cloudg-0.3.0/tests/test_rag_export.py +291 -0
  83. cloudg-0.3.0/tests/test_region_discovery.py +155 -0
  84. cloudg-0.3.0/tests/test_scanner_orchestration.py +254 -0
  85. cloudg-0.3.0/tests/test_terraform_export.py +371 -0
@@ -0,0 +1,69 @@
1
+ # ── Python ──
2
+ *.pyc
3
+ *.pyo
4
+ *.pyd
5
+ __pycache__/
6
+ *.egg-info/
7
+ *.egg
8
+ dist/
9
+ build/
10
+ *.whl
11
+
12
+ # ── Virtual Environments ──
13
+ .venv/
14
+ venv/
15
+ env/
16
+
17
+ # ── IDE ──
18
+ .idea/
19
+ .vscode/
20
+ *.swp
21
+ *.swo
22
+ *~
23
+ .project
24
+ .settings/
25
+
26
+ # ── Testing ──
27
+ .pytest_cache/
28
+ .coverage
29
+ htmlcov/
30
+ .tox/
31
+ .nox/
32
+
33
+ # ── Package managers ──
34
+ poetry.lock
35
+ uv.lock
36
+
37
+ # ── Claude workspace (never push) ──
38
+ .claude/
39
+
40
+ # ── OS ──
41
+ .DS_Store
42
+ Thumbs.db
43
+ *.bak
44
+ *.tmp
45
+
46
+ # ── Logs ──
47
+ *.log
48
+ logs/
49
+
50
+ # ── Reports (generated output) ──
51
+ reports/
52
+ *.graphml
53
+
54
+ # ── Terraform output ──
55
+ *.tf.json
56
+ .terraform/
57
+ terraform.tfstate*
58
+
59
+ # ── Secrets (NEVER commit) ──
60
+ .env
61
+ .env.*
62
+ config.yaml
63
+ !config.yaml.example
64
+
65
+ # ── Ontology/RAG output ──
66
+ *.ttl
67
+ *.jsonld
68
+ *.nt
69
+ rag_chunks/.ruff_cache/
cloudg-0.3.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 morpheuslord
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.
cloudg-0.3.0/PKG-INFO ADDED
@@ -0,0 +1,330 @@
1
+ Metadata-Version: 2.5
2
+ Name: cloudg
3
+ Version: 0.3.0
4
+ Summary: cloudg (cloud graphing) — multi-cloud infrastructure mapping, knowledge graphs and security intelligence for AWS, Azure and GCP
5
+ Project-URL: Homepage, https://github.com/morpheuslord/cloudg
6
+ Project-URL: Repository, https://github.com/morpheuslord/cloudg
7
+ Author-email: morpheuslord <chiranjeevi.naidu@proton.me>
8
+ License: MIT
9
+ License-File: LICENSE
10
+ Keywords: audit,aws,azure,cloud,gcp,graph,ontology,security,terraform
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Environment :: Console
13
+ Classifier: Intended Audience :: Information Technology
14
+ Classifier: Intended Audience :: System Administrators
15
+ Classifier: License :: OSI Approved :: MIT License
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Topic :: Security
19
+ Classifier: Topic :: System :: Systems Administration
20
+ Requires-Python: >=3.11
21
+ Requires-Dist: aiofiles>=23.0
22
+ Requires-Dist: click>=8.0
23
+ Requires-Dist: jinja2>=3.1
24
+ Requires-Dist: networkx>=3.1
25
+ Requires-Dist: parliament>=1.6
26
+ Requires-Dist: pydantic<3.0,>=2.0
27
+ Requires-Dist: python-louvain>=0.16
28
+ Requires-Dist: pyyaml>=6.0
29
+ Requires-Dist: rdflib>=7.0
30
+ Requires-Dist: rich>=13.0
31
+ Requires-Dist: svgwrite>=1.4
32
+ Provides-Extra: all
33
+ Requires-Dist: aioboto3>=12.0; extra == 'all'
34
+ Requires-Dist: azure-identity>=1.14; extra == 'all'
35
+ Requires-Dist: azure-mgmt-compute>=30.0; extra == 'all'
36
+ Requires-Dist: azure-mgmt-keyvault>=10.0; extra == 'all'
37
+ Requires-Dist: azure-mgmt-network>=25.0; extra == 'all'
38
+ Requires-Dist: azure-mgmt-resource>=23.0; extra == 'all'
39
+ Requires-Dist: azure-mgmt-sql>=3.0; extra == 'all'
40
+ Requires-Dist: azure-mgmt-storage>=21.0; extra == 'all'
41
+ Requires-Dist: boto3>=1.28; extra == 'all'
42
+ Requires-Dist: google-auth>=2.22; extra == 'all'
43
+ Requires-Dist: google-cloud-asset>=3.0; extra == 'all'
44
+ Provides-Extra: aws
45
+ Requires-Dist: aioboto3>=12.0; extra == 'aws'
46
+ Requires-Dist: boto3>=1.28; extra == 'aws'
47
+ Provides-Extra: azure
48
+ Requires-Dist: azure-identity>=1.14; extra == 'azure'
49
+ Requires-Dist: azure-mgmt-compute>=30.0; extra == 'azure'
50
+ Requires-Dist: azure-mgmt-keyvault>=10.0; extra == 'azure'
51
+ Requires-Dist: azure-mgmt-network>=25.0; extra == 'azure'
52
+ Requires-Dist: azure-mgmt-resource>=23.0; extra == 'azure'
53
+ Requires-Dist: azure-mgmt-sql>=3.0; extra == 'azure'
54
+ Requires-Dist: azure-mgmt-storage>=21.0; extra == 'azure'
55
+ Provides-Extra: dev
56
+ Requires-Dist: aioboto3>=12.0; extra == 'dev'
57
+ Requires-Dist: boto3>=1.28; extra == 'dev'
58
+ Requires-Dist: moto[all]>=5.0; extra == 'dev'
59
+ Requires-Dist: pytest-asyncio>=0.21; extra == 'dev'
60
+ Requires-Dist: pytest>=7.0; extra == 'dev'
61
+ Requires-Dist: ruff>=0.1; extra == 'dev'
62
+ Provides-Extra: full
63
+ Requires-Dist: diagrams>=0.23; extra == 'full'
64
+ Requires-Dist: policy-sentry>=0.12; extra == 'full'
65
+ Requires-Dist: weasyprint>=60.0; extra == 'full'
66
+ Provides-Extra: gcp
67
+ Requires-Dist: google-auth>=2.22; extra == 'gcp'
68
+ Requires-Dist: google-cloud-asset>=3.0; extra == 'gcp'
69
+ Description-Content-Type: text/markdown
70
+
71
+ <p align="center">
72
+ <img src="https://raw.githubusercontent.com/morpheuslord/cloudg/main/assets/cloudg_animated_logo.gif" width="600" alt="cloudg animated logo">
73
+ </p>
74
+
75
+ <p align="center">
76
+ <a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-green.svg" alt="License: MIT"></a>
77
+ <img src="https://img.shields.io/badge/python-3.11%2B-blue.svg" alt="Python 3.11+">
78
+ <img src="https://img.shields.io/badge/version-0.3.0-4c1.svg" alt="Version 0.3.0">
79
+ <a href="https://github.com/astral-sh/uv"><img src="https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/uv/main/assets/badge/v0.json" alt="uv"></a>
80
+ </p>
81
+
82
+ <p align="center">
83
+ <b>cloudg</b> (cloud graphing) maps AWS, Azure and GCP infrastructure into a graph,<br>
84
+ runs security scanners over the same inventory, and turns the results into reports you can actually use.
85
+ </p>
86
+
87
+ ---
88
+
89
+ One command collects assets from every configured provider in parallel, feeds them through a NetworkX graph for reachability and attack path analysis, fans out to Prowler, ScoutSuite, Checkov and Trivy, then merges and deduplicates all findings against 28 compliance frameworks. Out the other end come an interactive HTML report, GraphML, an RDF ontology, RAG chunks for LLM pipelines, and Terraform files that recreate the live infrastructure.
90
+
91
+ ---
92
+
93
+ ## Quick start
94
+
95
+ ```bash
96
+ git clone https://github.com/morpheuslord/cloudg.git
97
+ cd cloudg
98
+
99
+ uv venv && source .venv/bin/activate
100
+ uv pip install -e ".[all,dev]"
101
+ ```
102
+
103
+ ```bash
104
+ # one provider, one region
105
+ cloudg run -p aws --regions us-east-1
106
+
107
+ # everything, everywhere
108
+ cloudg run -p all --regions all
109
+
110
+ # with Terraform recreation files
111
+ cloudg run -p aws --regions us-east-1 --terraform
112
+ ```
113
+
114
+ Reports land in `./reports`. Open `report.html` first.
115
+
116
+ <details>
117
+ <summary><b>Other install options (pip, Docker, installer scripts)</b></summary>
118
+
119
+ <br>
120
+
121
+ Plain pip works too: `pip install -e ".[all]"`. The cloud SDKs are extras, so `pip install cloudg[aws]` pulls only boto3/aioboto3, `[azure]` and `[gcp]` do the same for their SDKs, and `[all]` installs the lot. The core package with no extras still gives you the graph engine, the ontology, the normaliser and the report renderers.
122
+
123
+ The external scanners (Prowler, Checkov, Trivy, ScoutSuite) are separate executables, not Python dependencies. `install.sh` (Linux/macOS) and `install.bat` (Windows) set up everything including the scanners and the cloud CLIs.
124
+
125
+ Docker is the lazy path, since the image bundles all four scanners:
126
+
127
+ ```bash
128
+ docker build -t cloudg:latest .
129
+ docker compose run --rm cloudg run -p aws --regions us-east-1
130
+ ```
131
+
132
+ </details>
133
+
134
+ ---
135
+
136
+ ## Authentication
137
+
138
+ Every provider supports several auth methods, resolved in a fixed priority order. The same config works on a laptop, in CI, and on cloud compute. The full set of fields lives in `config.yaml` with comments for each method.
139
+
140
+ <details>
141
+ <summary><b>AWS</b></summary>
142
+
143
+ <br>
144
+
145
+ 1. Direct keys: `--aws-key` / `--aws-secret` (plus `--aws-session-token` for temporary credentials), or the standard env vars.
146
+ 2. OIDC web identity federation: `--aws-role-arn` together with `--aws-web-identity-token-file`. This is the GitHub Actions / GitLab CI / EKS service account pattern, no long-lived keys anywhere.
147
+ 3. A named CLI profile via `--profile`, including SSO profiles.
148
+ 4. Nothing at all: the default chain picks up env vars, cached SSO credentials, or the EC2/ECS instance role, so a scan running on cloud compute inherits its host's role.
149
+
150
+ On top of any of these you can layer STS role assumption with `--aws-role-arn` and, for the third-party auditor pattern, `--aws-external-id`. Multi-account fan-out uses `accounts` plus `role_name` in the config file, and cloudg assumes that role in each account before collecting.
151
+
152
+ </details>
153
+
154
+ <details>
155
+ <summary><b>Azure</b></summary>
156
+
157
+ <br>
158
+
159
+ 1. Workload identity federation: `--azure-tenant-id`, `--azure-client-id` and `--azure-federated-token-file` (AKS workload identity, GitHub OIDC).
160
+ 2. Service principal with a client secret: `--azure-client-secret`.
161
+ 3. Service principal with a certificate: `--azure-cert-path`.
162
+ 4. Managed identity: `--azure-managed-identity`, with `managed_identity_client_id` in the config for user-assigned identities.
163
+ 5. The DefaultAzureCredential chain, which also covers `az login` sessions.
164
+
165
+ </details>
166
+
167
+ <details>
168
+ <summary><b>GCP</b></summary>
169
+
170
+ <br>
171
+
172
+ 1. A credentials file via `--gcp-credentials-file`: either a service account key JSON or a workload identity federation (`external_account`) config.
173
+ 2. Application default credentials: `GOOGLE_APPLICATION_CREDENTIALS`, gcloud user credentials, or the GCE/GKE metadata server.
174
+
175
+ `--gcp-impersonate-sa` layers service account impersonation on top of either, which is handy when your user account may impersonate a read-only scanner service account.
176
+
177
+ </details>
178
+
179
+ ---
180
+
181
+ ## What the pipeline does
182
+
183
+ ```mermaid
184
+ graph LR
185
+ A[Collect<br/>AWS + Azure + GCP] --> B[Graph<br/>reachability, attack paths]
186
+ A --> C[Scanners<br/>Prowler, Checkov, Trivy, ScoutSuite]
187
+ B --> D[Ontology + RAG + Terraform]
188
+ C --> E[Normalise<br/>dedupe, score, map to frameworks]
189
+ D --> F[Reports]
190
+ E --> F
191
+ ```
192
+
193
+ Collection runs all providers concurrently with asyncio, iterating accounts and regions per provider (regions are auto-discovered when you pass `--regions all`). Assets and network edges go into a directed graph, where BFS from the internet node finds exposed resources and blast radius scoring estimates what an attacker could reach from each node.
194
+
195
+ The same inventory feeds three other exports. The ontology module infers about 62 typed relations (`exposed_to_internet`, `assumes_role`, `encrypted_by`, `hosted_in_vpc` and so on) and writes RDF you can query with SPARQL. The RAG exporter chunks the graph three ways (per asset, per Louvain community, per relation domain) into JSONL for retrieval pipelines. The Terraform exporter maps 25+ asset types to `.tf.json` resources with an `import.sh` to adopt them into state.
196
+
197
+ Scanner findings are deduplicated by resource and title, rescored against CVSS, and mapped to compliance controls.
198
+
199
+ ---
200
+
201
+ ## Compliance rules
202
+
203
+ Findings are tagged with framework controls in four tiers, most precise first:
204
+
205
+ 1. Whatever the scanner itself reports (Prowler ASFF, Checkov check IDs).
206
+ 2. Exact check-ID lookup against the shipped rulesets. These are generated from Prowler's public compliance data (Apache-2.0) and cover 28 frameworks with 4,166 controls and 10,236 check mappings across AWS, Azure and GCP: CIS 5.0 for each cloud, NIST 800-53 rev 5, NIST CSF 2.0, PCI DSS 4.0, SOC 2, HIPAA, GDPR, ISO 27001:2022, MITRE ATT&CK, and the AWS Foundational Security Best Practices.
207
+ 3. Regex pattern rules for scanners that emit no compliance metadata.
208
+ 4. A small built-in fallback table.
209
+
210
+ <details>
211
+ <summary><b>Refreshing and extending the rulesets</b></summary>
212
+
213
+ <br>
214
+
215
+ The rulesets ship inside the package (`cloudg/rules/`). To refresh them against a newer Prowler release:
216
+
217
+ ```bash
218
+ git clone --depth 1 https://github.com/prowler-cloud/prowler /tmp/prowler
219
+ python scripts/import_prowler_compliance.py /tmp/prowler
220
+ ```
221
+
222
+ Adding your own framework is a YAML file in the rules directory:
223
+
224
+ ```yaml
225
+ framework: MY-FRAMEWORK
226
+ controls:
227
+ - id: "MF-1.1"
228
+ title: "Storage is encrypted"
229
+ patterns: ["encrypt.*rest"] # regex tier
230
+ checks: ["s3_default_encryption"] # exact tier, optional
231
+ ```
232
+
233
+ `cloudg/policies/` additionally holds Cloud Custodian policy packs (AWS governance, AWS security, Azure, GCP) you can run with `custodian run` independently of cloudg.
234
+
235
+ </details>
236
+
237
+ ---
238
+
239
+ ## Reference
240
+
241
+ <details>
242
+ <summary><b>CLI flags</b></summary>
243
+
244
+ <br>
245
+
246
+ | Flag | Meaning |
247
+ |---|---|
248
+ | `-p, --provider` | `aws`, `azure`, `gcp` or `all`; repeatable |
249
+ | `--regions` | `all` for auto-discovery, or a comma-separated list |
250
+ | `--aws-key`, `--aws-secret`, `--aws-session-token` | direct AWS credentials |
251
+ | `--aws-role-arn`, `--aws-external-id` | STS role assumption |
252
+ | `--aws-web-identity-token-file` | OIDC token file for web identity federation |
253
+ | `--profile` | AWS CLI profile |
254
+ | `--subscription-id`, `--azure-tenant-id`, `--azure-client-id` | Azure identity |
255
+ | `--azure-client-secret`, `--azure-cert-path` | service principal credentials |
256
+ | `--azure-federated-token-file`, `--azure-managed-identity` | federation / managed identity |
257
+ | `--project-id`, `--gcp-credentials-file`, `--gcp-impersonate-sa` | GCP identity |
258
+ | `--scanners` | comma-separated subset of `prowler,scoutsuite,checkov,trivy,iam` |
259
+ | `--iac-dir` | directory for Checkov to scan |
260
+ | `--images` | container images for Trivy |
261
+ | `--ontology/--no-ontology` | RDF ontology export (on by default) |
262
+ | `--rag-export/--no-rag-export` | RAG chunk export (on by default) |
263
+ | `--terraform/--no-terraform` | Terraform recreation (off by default) |
264
+ | `-o, --output` | output directory, `./reports` by default |
265
+
266
+ `cloudg collect` and `cloudg scan` run the individual phases; `cloudg report -i findings.json` re-renders reports from a previous run.
267
+
268
+ </details>
269
+
270
+ <details>
271
+ <summary><b>Output files</b></summary>
272
+
273
+ <br>
274
+
275
+ | File | What it is |
276
+ |---|---|
277
+ | `report.html` | interactive report, D3 topology plus findings table, works offline |
278
+ | `findings.json` | all findings, assets, edges and compliance results |
279
+ | `topology.svg`, `topology.graphml`, `topology-cytoscape.json` | the graph in three formats |
280
+ | `ontology.ttl`, `ontology.jsonld` | the RDF ontology |
281
+ | `rag_chunks.jsonl`, `rag_metadata_index.json` | retrieval-ready chunks |
282
+ | `terraform/*.tf.json`, `terraform/import.sh` | recreation files |
283
+
284
+ </details>
285
+
286
+ ---
287
+
288
+ ## Using it as a library
289
+
290
+ ```python
291
+ from cloudg import CloudGConfig, CloudGEngine
292
+
293
+ config = CloudGConfig(providers=["aws"])
294
+ config.aws.role_arn = "arn:aws:iam::123456789012:role/scanner"
295
+ config.aws.external_id = "my-external-id"
296
+
297
+ engine = CloudGEngine(config)
298
+ engine.on_finding = lambda f: forward_to_siem(f)
299
+
300
+ result = engine.run_pipeline_sync()
301
+ print(result.to_summary())
302
+ ```
303
+
304
+ The engine exposes `collect()`, `scan()` and `analyze()` separately if you only need part of the pipeline, and event hooks (`on_finding`, `on_phase_start`, `on_error`, `on_scan_complete`) for streaming integration.
305
+
306
+ Custom collectors and scanners register through entry points, no core changes needed:
307
+
308
+ ```toml
309
+ [project.entry-points."cloudg.collectors"]
310
+ mycloud = "my_package.collector:MyCollector"
311
+ ```
312
+
313
+ ---
314
+
315
+ ## Development
316
+
317
+ ```bash
318
+ uv pip install -e ".[all,dev]"
319
+ pytest # 152 tests, moto-mocked AWS included
320
+ ruff check cloudg/ tests/
321
+ uv build # wheel + sdist for PyPI
322
+ ```
323
+
324
+ Python 3.11 or newer. The moto/aiobotocore incompatibility around async response bodies is handled in `tests/conftest.py`, so the suite runs against current versions of both.
325
+
326
+ ---
327
+
328
+ ## License
329
+
330
+ MIT
cloudg-0.3.0/README.md ADDED
@@ -0,0 +1,260 @@
1
+ <p align="center">
2
+ <img src="https://raw.githubusercontent.com/morpheuslord/cloudg/main/assets/cloudg_animated_logo.gif" width="600" alt="cloudg animated logo">
3
+ </p>
4
+
5
+ <p align="center">
6
+ <a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-green.svg" alt="License: MIT"></a>
7
+ <img src="https://img.shields.io/badge/python-3.11%2B-blue.svg" alt="Python 3.11+">
8
+ <img src="https://img.shields.io/badge/version-0.3.0-4c1.svg" alt="Version 0.3.0">
9
+ <a href="https://github.com/astral-sh/uv"><img src="https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/uv/main/assets/badge/v0.json" alt="uv"></a>
10
+ </p>
11
+
12
+ <p align="center">
13
+ <b>cloudg</b> (cloud graphing) maps AWS, Azure and GCP infrastructure into a graph,<br>
14
+ runs security scanners over the same inventory, and turns the results into reports you can actually use.
15
+ </p>
16
+
17
+ ---
18
+
19
+ One command collects assets from every configured provider in parallel, feeds them through a NetworkX graph for reachability and attack path analysis, fans out to Prowler, ScoutSuite, Checkov and Trivy, then merges and deduplicates all findings against 28 compliance frameworks. Out the other end come an interactive HTML report, GraphML, an RDF ontology, RAG chunks for LLM pipelines, and Terraform files that recreate the live infrastructure.
20
+
21
+ ---
22
+
23
+ ## Quick start
24
+
25
+ ```bash
26
+ git clone https://github.com/morpheuslord/cloudg.git
27
+ cd cloudg
28
+
29
+ uv venv && source .venv/bin/activate
30
+ uv pip install -e ".[all,dev]"
31
+ ```
32
+
33
+ ```bash
34
+ # one provider, one region
35
+ cloudg run -p aws --regions us-east-1
36
+
37
+ # everything, everywhere
38
+ cloudg run -p all --regions all
39
+
40
+ # with Terraform recreation files
41
+ cloudg run -p aws --regions us-east-1 --terraform
42
+ ```
43
+
44
+ Reports land in `./reports`. Open `report.html` first.
45
+
46
+ <details>
47
+ <summary><b>Other install options (pip, Docker, installer scripts)</b></summary>
48
+
49
+ <br>
50
+
51
+ Plain pip works too: `pip install -e ".[all]"`. The cloud SDKs are extras, so `pip install cloudg[aws]` pulls only boto3/aioboto3, `[azure]` and `[gcp]` do the same for their SDKs, and `[all]` installs the lot. The core package with no extras still gives you the graph engine, the ontology, the normaliser and the report renderers.
52
+
53
+ The external scanners (Prowler, Checkov, Trivy, ScoutSuite) are separate executables, not Python dependencies. `install.sh` (Linux/macOS) and `install.bat` (Windows) set up everything including the scanners and the cloud CLIs.
54
+
55
+ Docker is the lazy path, since the image bundles all four scanners:
56
+
57
+ ```bash
58
+ docker build -t cloudg:latest .
59
+ docker compose run --rm cloudg run -p aws --regions us-east-1
60
+ ```
61
+
62
+ </details>
63
+
64
+ ---
65
+
66
+ ## Authentication
67
+
68
+ Every provider supports several auth methods, resolved in a fixed priority order. The same config works on a laptop, in CI, and on cloud compute. The full set of fields lives in `config.yaml` with comments for each method.
69
+
70
+ <details>
71
+ <summary><b>AWS</b></summary>
72
+
73
+ <br>
74
+
75
+ 1. Direct keys: `--aws-key` / `--aws-secret` (plus `--aws-session-token` for temporary credentials), or the standard env vars.
76
+ 2. OIDC web identity federation: `--aws-role-arn` together with `--aws-web-identity-token-file`. This is the GitHub Actions / GitLab CI / EKS service account pattern, no long-lived keys anywhere.
77
+ 3. A named CLI profile via `--profile`, including SSO profiles.
78
+ 4. Nothing at all: the default chain picks up env vars, cached SSO credentials, or the EC2/ECS instance role, so a scan running on cloud compute inherits its host's role.
79
+
80
+ On top of any of these you can layer STS role assumption with `--aws-role-arn` and, for the third-party auditor pattern, `--aws-external-id`. Multi-account fan-out uses `accounts` plus `role_name` in the config file, and cloudg assumes that role in each account before collecting.
81
+
82
+ </details>
83
+
84
+ <details>
85
+ <summary><b>Azure</b></summary>
86
+
87
+ <br>
88
+
89
+ 1. Workload identity federation: `--azure-tenant-id`, `--azure-client-id` and `--azure-federated-token-file` (AKS workload identity, GitHub OIDC).
90
+ 2. Service principal with a client secret: `--azure-client-secret`.
91
+ 3. Service principal with a certificate: `--azure-cert-path`.
92
+ 4. Managed identity: `--azure-managed-identity`, with `managed_identity_client_id` in the config for user-assigned identities.
93
+ 5. The DefaultAzureCredential chain, which also covers `az login` sessions.
94
+
95
+ </details>
96
+
97
+ <details>
98
+ <summary><b>GCP</b></summary>
99
+
100
+ <br>
101
+
102
+ 1. A credentials file via `--gcp-credentials-file`: either a service account key JSON or a workload identity federation (`external_account`) config.
103
+ 2. Application default credentials: `GOOGLE_APPLICATION_CREDENTIALS`, gcloud user credentials, or the GCE/GKE metadata server.
104
+
105
+ `--gcp-impersonate-sa` layers service account impersonation on top of either, which is handy when your user account may impersonate a read-only scanner service account.
106
+
107
+ </details>
108
+
109
+ ---
110
+
111
+ ## What the pipeline does
112
+
113
+ ```mermaid
114
+ graph LR
115
+ A[Collect<br/>AWS + Azure + GCP] --> B[Graph<br/>reachability, attack paths]
116
+ A --> C[Scanners<br/>Prowler, Checkov, Trivy, ScoutSuite]
117
+ B --> D[Ontology + RAG + Terraform]
118
+ C --> E[Normalise<br/>dedupe, score, map to frameworks]
119
+ D --> F[Reports]
120
+ E --> F
121
+ ```
122
+
123
+ Collection runs all providers concurrently with asyncio, iterating accounts and regions per provider (regions are auto-discovered when you pass `--regions all`). Assets and network edges go into a directed graph, where BFS from the internet node finds exposed resources and blast radius scoring estimates what an attacker could reach from each node.
124
+
125
+ The same inventory feeds three other exports. The ontology module infers about 62 typed relations (`exposed_to_internet`, `assumes_role`, `encrypted_by`, `hosted_in_vpc` and so on) and writes RDF you can query with SPARQL. The RAG exporter chunks the graph three ways (per asset, per Louvain community, per relation domain) into JSONL for retrieval pipelines. The Terraform exporter maps 25+ asset types to `.tf.json` resources with an `import.sh` to adopt them into state.
126
+
127
+ Scanner findings are deduplicated by resource and title, rescored against CVSS, and mapped to compliance controls.
128
+
129
+ ---
130
+
131
+ ## Compliance rules
132
+
133
+ Findings are tagged with framework controls in four tiers, most precise first:
134
+
135
+ 1. Whatever the scanner itself reports (Prowler ASFF, Checkov check IDs).
136
+ 2. Exact check-ID lookup against the shipped rulesets. These are generated from Prowler's public compliance data (Apache-2.0) and cover 28 frameworks with 4,166 controls and 10,236 check mappings across AWS, Azure and GCP: CIS 5.0 for each cloud, NIST 800-53 rev 5, NIST CSF 2.0, PCI DSS 4.0, SOC 2, HIPAA, GDPR, ISO 27001:2022, MITRE ATT&CK, and the AWS Foundational Security Best Practices.
137
+ 3. Regex pattern rules for scanners that emit no compliance metadata.
138
+ 4. A small built-in fallback table.
139
+
140
+ <details>
141
+ <summary><b>Refreshing and extending the rulesets</b></summary>
142
+
143
+ <br>
144
+
145
+ The rulesets ship inside the package (`cloudg/rules/`). To refresh them against a newer Prowler release:
146
+
147
+ ```bash
148
+ git clone --depth 1 https://github.com/prowler-cloud/prowler /tmp/prowler
149
+ python scripts/import_prowler_compliance.py /tmp/prowler
150
+ ```
151
+
152
+ Adding your own framework is a YAML file in the rules directory:
153
+
154
+ ```yaml
155
+ framework: MY-FRAMEWORK
156
+ controls:
157
+ - id: "MF-1.1"
158
+ title: "Storage is encrypted"
159
+ patterns: ["encrypt.*rest"] # regex tier
160
+ checks: ["s3_default_encryption"] # exact tier, optional
161
+ ```
162
+
163
+ `cloudg/policies/` additionally holds Cloud Custodian policy packs (AWS governance, AWS security, Azure, GCP) you can run with `custodian run` independently of cloudg.
164
+
165
+ </details>
166
+
167
+ ---
168
+
169
+ ## Reference
170
+
171
+ <details>
172
+ <summary><b>CLI flags</b></summary>
173
+
174
+ <br>
175
+
176
+ | Flag | Meaning |
177
+ |---|---|
178
+ | `-p, --provider` | `aws`, `azure`, `gcp` or `all`; repeatable |
179
+ | `--regions` | `all` for auto-discovery, or a comma-separated list |
180
+ | `--aws-key`, `--aws-secret`, `--aws-session-token` | direct AWS credentials |
181
+ | `--aws-role-arn`, `--aws-external-id` | STS role assumption |
182
+ | `--aws-web-identity-token-file` | OIDC token file for web identity federation |
183
+ | `--profile` | AWS CLI profile |
184
+ | `--subscription-id`, `--azure-tenant-id`, `--azure-client-id` | Azure identity |
185
+ | `--azure-client-secret`, `--azure-cert-path` | service principal credentials |
186
+ | `--azure-federated-token-file`, `--azure-managed-identity` | federation / managed identity |
187
+ | `--project-id`, `--gcp-credentials-file`, `--gcp-impersonate-sa` | GCP identity |
188
+ | `--scanners` | comma-separated subset of `prowler,scoutsuite,checkov,trivy,iam` |
189
+ | `--iac-dir` | directory for Checkov to scan |
190
+ | `--images` | container images for Trivy |
191
+ | `--ontology/--no-ontology` | RDF ontology export (on by default) |
192
+ | `--rag-export/--no-rag-export` | RAG chunk export (on by default) |
193
+ | `--terraform/--no-terraform` | Terraform recreation (off by default) |
194
+ | `-o, --output` | output directory, `./reports` by default |
195
+
196
+ `cloudg collect` and `cloudg scan` run the individual phases; `cloudg report -i findings.json` re-renders reports from a previous run.
197
+
198
+ </details>
199
+
200
+ <details>
201
+ <summary><b>Output files</b></summary>
202
+
203
+ <br>
204
+
205
+ | File | What it is |
206
+ |---|---|
207
+ | `report.html` | interactive report, D3 topology plus findings table, works offline |
208
+ | `findings.json` | all findings, assets, edges and compliance results |
209
+ | `topology.svg`, `topology.graphml`, `topology-cytoscape.json` | the graph in three formats |
210
+ | `ontology.ttl`, `ontology.jsonld` | the RDF ontology |
211
+ | `rag_chunks.jsonl`, `rag_metadata_index.json` | retrieval-ready chunks |
212
+ | `terraform/*.tf.json`, `terraform/import.sh` | recreation files |
213
+
214
+ </details>
215
+
216
+ ---
217
+
218
+ ## Using it as a library
219
+
220
+ ```python
221
+ from cloudg import CloudGConfig, CloudGEngine
222
+
223
+ config = CloudGConfig(providers=["aws"])
224
+ config.aws.role_arn = "arn:aws:iam::123456789012:role/scanner"
225
+ config.aws.external_id = "my-external-id"
226
+
227
+ engine = CloudGEngine(config)
228
+ engine.on_finding = lambda f: forward_to_siem(f)
229
+
230
+ result = engine.run_pipeline_sync()
231
+ print(result.to_summary())
232
+ ```
233
+
234
+ The engine exposes `collect()`, `scan()` and `analyze()` separately if you only need part of the pipeline, and event hooks (`on_finding`, `on_phase_start`, `on_error`, `on_scan_complete`) for streaming integration.
235
+
236
+ Custom collectors and scanners register through entry points, no core changes needed:
237
+
238
+ ```toml
239
+ [project.entry-points."cloudg.collectors"]
240
+ mycloud = "my_package.collector:MyCollector"
241
+ ```
242
+
243
+ ---
244
+
245
+ ## Development
246
+
247
+ ```bash
248
+ uv pip install -e ".[all,dev]"
249
+ pytest # 152 tests, moto-mocked AWS included
250
+ ruff check cloudg/ tests/
251
+ uv build # wheel + sdist for PyPI
252
+ ```
253
+
254
+ Python 3.11 or newer. The moto/aiobotocore incompatibility around async response bodies is handled in `tests/conftest.py`, so the suite runs against current versions of both.
255
+
256
+ ---
257
+
258
+ ## License
259
+
260
+ MIT