cloudsplaining 0.8.0__tar.gz → 0.8.2__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.
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/PKG-INFO +44 -2
- cloudsplaining-0.8.0/cloudsplaining.egg-info/PKG-INFO → cloudsplaining-0.8.2/README.md +41 -29
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/cloudsplaining/bin/version.py +1 -1
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/cloudsplaining/command/create_exclusions_file.py +2 -2
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/cloudsplaining/command/create_multi_account_config_file.py +2 -2
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/cloudsplaining/command/scan.py +14 -0
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/cloudsplaining/command/scan_multi_account.py +14 -0
- cloudsplaining-0.8.2/cloudsplaining/output/dist/js/index.js +63 -0
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/cloudsplaining/output/report.py +6 -0
- cloudsplaining-0.8.2/cloudsplaining/output/src/App.vue +197 -0
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/cloudsplaining/output/src/routes/routes.js +21 -11
- cloudsplaining-0.8.2/cloudsplaining/output/src/views/Appendices.vue +21 -0
- cloudsplaining-0.8.2/cloudsplaining/output/src/views/Guidance.vue +21 -0
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/cloudsplaining/output/template.html +8 -0
- cloudsplaining-0.8.2/cloudsplaining/scan/assume_role_policy_document.py +209 -0
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/cloudsplaining/scan/authorization_details.py +3 -0
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/cloudsplaining/scan/inline_policy.py +1 -1
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/cloudsplaining/scan/managed_policy_detail.py +1 -1
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/cloudsplaining/scan/role_details.py +71 -4
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/cloudsplaining/scan/statement_detail.py +1 -2
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/cloudsplaining/shared/constants.py +12 -0
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/cloudsplaining/shared/default-exclusions.yml +6 -1
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/cloudsplaining/shared/exclusions.py +7 -0
- cloudsplaining-0.8.2/cloudsplaining/shared/template_config.py +41 -0
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/cloudsplaining/shared/utils.py +14 -0
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/cloudsplaining/shared/validation.py +1 -0
- cloudsplaining-0.8.0/README.md → cloudsplaining-0.8.2/cloudsplaining.egg-info/PKG-INFO +71 -0
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/cloudsplaining.egg-info/SOURCES.txt +1 -0
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/pyproject.toml +5 -0
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/setup.py +2 -1
- cloudsplaining-0.8.0/cloudsplaining/output/dist/js/index.js +0 -63
- cloudsplaining-0.8.0/cloudsplaining/output/src/App.vue +0 -174
- cloudsplaining-0.8.0/cloudsplaining/output/src/views/Appendices.vue +0 -12
- cloudsplaining-0.8.0/cloudsplaining/output/src/views/Guidance.vue +0 -12
- cloudsplaining-0.8.0/cloudsplaining/scan/assume_role_policy_document.py +0 -91
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/LICENSE +0 -0
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/MANIFEST.in +0 -0
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/cloudsplaining/__init__.py +0 -0
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/cloudsplaining/bin/__init__.py +0 -0
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/cloudsplaining/bin/cli.py +0 -0
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/cloudsplaining/command/__init__.py +0 -0
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/cloudsplaining/command/download.py +0 -0
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/cloudsplaining/command/expand_policy.py +0 -0
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/cloudsplaining/command/scan_policy_file.py +0 -0
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/cloudsplaining/output/__init__.py +0 -0
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/cloudsplaining/output/dist/index.html +0 -0
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/cloudsplaining/output/dist/js/chunk-vendors.js +0 -0
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/cloudsplaining/output/policy_finding.py +0 -0
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/cloudsplaining/output/public/index.html +0 -0
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/cloudsplaining/output/src/assets/1-overview.md +0 -0
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/cloudsplaining/output/src/assets/2-triage-guidance.md +0 -0
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/cloudsplaining/output/src/assets/3-remediation-guidance.md +0 -0
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/cloudsplaining/output/src/assets/4-validation.md +0 -0
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/cloudsplaining/output/src/assets/definition-assumable-by-compute-service.md +0 -0
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/cloudsplaining/output/src/assets/definition-credentials-exposure.md +0 -0
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/cloudsplaining/output/src/assets/definition-data-exfiltration.md +0 -0
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/cloudsplaining/output/src/assets/definition-infrastructure-modification.md +0 -0
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/cloudsplaining/output/src/assets/definition-privilege-escalation.md +0 -0
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/cloudsplaining/output/src/assets/definition-resource-exposure.md +0 -0
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/cloudsplaining/output/src/assets/definition-service-wildcard.md +0 -0
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/cloudsplaining/output/src/assets/glossary.md +0 -0
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/cloudsplaining/output/src/assets/how-do-i-validate-results.md +0 -0
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/cloudsplaining/output/src/assets/identifying-false-positives.md +0 -0
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/cloudsplaining/output/src/assets/logo.png +0 -0
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/cloudsplaining/output/src/assets/summary.md +0 -0
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/cloudsplaining/output/src/assets/what-should-i-do.md +0 -0
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/cloudsplaining/output/src/components/Appendix.vue +0 -0
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/cloudsplaining/output/src/components/Button.vue +0 -0
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/cloudsplaining/output/src/components/Glossary.vue +0 -0
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/cloudsplaining/output/src/components/Guidance.vue +0 -0
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/cloudsplaining/output/src/components/InlinePolicies.vue +0 -0
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/cloudsplaining/output/src/components/LinkToFinding.vue +0 -0
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/cloudsplaining/output/src/components/ManagedPolicies.vue +0 -0
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/cloudsplaining/output/src/components/PolicyTable.vue +0 -0
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/cloudsplaining/output/src/components/Principals.vue +0 -0
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/cloudsplaining/output/src/components/ReportMetadata.vue +0 -0
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/cloudsplaining/output/src/components/Summary.vue +0 -0
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/cloudsplaining/output/src/components/TaskTable.vue +0 -0
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/cloudsplaining/output/src/components/charts/SummaryFindings.vue +0 -0
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/cloudsplaining/output/src/components/finding/AssumeRoleDetails.vue +0 -0
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/cloudsplaining/output/src/components/finding/FindingCard.vue +0 -0
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/cloudsplaining/output/src/components/finding/FindingDetails.vue +0 -0
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/cloudsplaining/output/src/components/finding/PolicyDocumentDetails.vue +0 -0
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/cloudsplaining/output/src/components/finding/PrivilegeEscalationDetails.vue +0 -0
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/cloudsplaining/output/src/components/finding/PrivilegeEscalationFormat.vue +0 -0
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/cloudsplaining/output/src/components/finding/RiskAlertIndicators.vue +0 -0
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/cloudsplaining/output/src/components/finding/StandardRiskDetails.vue +0 -0
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/cloudsplaining/output/src/components/principals/PrincipalMetadata.vue +0 -0
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/cloudsplaining/output/src/components/principals/RisksPerPrincipal.vue +0 -0
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/cloudsplaining/output/src/main.js +0 -0
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/cloudsplaining/output/src/sampleData.js +0 -0
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/cloudsplaining/output/src/test/groups-test.js +0 -0
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/cloudsplaining/output/src/test/inline-policies-test.js +0 -0
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/cloudsplaining/output/src/test/managed-policies-test.js +0 -0
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/cloudsplaining/output/src/test/other-test.js +0 -0
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/cloudsplaining/output/src/test/principals-test.js +0 -0
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/cloudsplaining/output/src/test/roles-test.js +0 -0
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/cloudsplaining/output/src/test/task-table-test.js +0 -0
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/cloudsplaining/output/src/util/glossary.js +0 -0
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/cloudsplaining/output/src/util/groups.js +0 -0
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/cloudsplaining/output/src/util/inline-policies.js +0 -0
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/cloudsplaining/output/src/util/managed-policies.js +0 -0
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/cloudsplaining/output/src/util/other.js +0 -0
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/cloudsplaining/output/src/util/principals.js +0 -0
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/cloudsplaining/output/src/util/roles.js +0 -0
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/cloudsplaining/output/src/util/task-table.js +0 -0
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/cloudsplaining/output/src/views/AwsPolicies.vue +0 -0
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/cloudsplaining/output/src/views/CustomerPolicies.vue +0 -0
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/cloudsplaining/output/src/views/IamPrincipals.vue +0 -0
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/cloudsplaining/output/src/views/InlinePolicies.vue +0 -0
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/cloudsplaining/output/src/views/Summary.vue +0 -0
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/cloudsplaining/py.typed +0 -0
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/cloudsplaining/scan/__init__.py +0 -0
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/cloudsplaining/scan/group_details.py +0 -0
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/cloudsplaining/scan/policy_document.py +0 -0
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/cloudsplaining/scan/resource_policy_document.py +0 -0
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/cloudsplaining/scan/user_details.py +0 -0
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/cloudsplaining/shared/__init__.py +0 -0
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/cloudsplaining/shared/aws_login.py +0 -0
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/cloudsplaining/shared/exceptions.py +0 -0
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/cloudsplaining/shared/multi-account-config.yml +0 -0
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/cloudsplaining.egg-info/dependency_links.txt +0 -0
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/cloudsplaining.egg-info/entry_points.txt +0 -0
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/cloudsplaining.egg-info/requires.txt +0 -0
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/cloudsplaining.egg-info/top_level.txt +0 -0
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/cloudsplaining.egg-info/zip-safe +0 -0
- {cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: cloudsplaining
|
|
3
|
-
Version: 0.8.
|
|
3
|
+
Version: 0.8.2
|
|
4
4
|
Summary: AWS IAM Security Assessment tool that identifies violations of least privilege and generates a risk-prioritized HTML report.
|
|
5
5
|
Home-page: https://github.com/salesforce/cloudsplaining
|
|
6
6
|
Author: Kinnaird McQuade
|
|
@@ -19,9 +19,10 @@ Classifier: Programming Language :: Python :: 3.10
|
|
|
19
19
|
Classifier: Programming Language :: Python :: 3.11
|
|
20
20
|
Classifier: Programming Language :: Python :: 3.12
|
|
21
21
|
Classifier: Programming Language :: Python :: 3.13
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
22
23
|
Classifier: License :: OSI Approved :: MIT License
|
|
23
24
|
Classifier: Operating System :: OS Independent
|
|
24
|
-
Requires-Python: >=3.
|
|
25
|
+
Requires-Python: >=3.9
|
|
25
26
|
Description-Content-Type: text/markdown
|
|
26
27
|
License-File: LICENSE
|
|
27
28
|
|
|
@@ -359,6 +360,47 @@ cloudsplaining scan-multi-account \
|
|
|
359
360
|
|
|
360
361
|
> Note that if you run the above without the `--profile` flag, it will execute in the standard [AWS Credentials order of precedence](https://docs.aws.amazon.com/sdk-for-java/v1/developer-guide/credentials.html#credentials-default) (i.e., Environment variables, credentials profiles, ECS container credentials, then finally EC2 Instance Profile credentials).
|
|
361
362
|
|
|
363
|
+
## Custom Guidance and Appendices
|
|
364
|
+
|
|
365
|
+
Cloudsplaining supports customizing the Guidance and Appendices sections of the HTML report to include organization-specific security recommendations and documentation.
|
|
366
|
+
|
|
367
|
+
### How It Works
|
|
368
|
+
|
|
369
|
+
Place HTML files in your project root directory:
|
|
370
|
+
|
|
371
|
+
- `custom-guidance.html` - Custom security guidance content
|
|
372
|
+
- `custom-appendices.html` - Custom appendices content
|
|
373
|
+
|
|
374
|
+
### Behavior
|
|
375
|
+
|
|
376
|
+
- **Files don't exist**: Shows default AWS security advice
|
|
377
|
+
- **Files exist with content**: Shows your custom HTML content
|
|
378
|
+
- **Files exist but are empty**: Hides the tabs entirely
|
|
379
|
+
- **Mixed configuration**: Each tab works independently
|
|
380
|
+
|
|
381
|
+
### Example Usage
|
|
382
|
+
|
|
383
|
+
```bash
|
|
384
|
+
# Create custom guidance
|
|
385
|
+
echo '<h1>Company Security Guidelines</h1>
|
|
386
|
+
<p>Follow these organization-specific steps:</p>
|
|
387
|
+
<ul>
|
|
388
|
+
<li>Review with security team</li>
|
|
389
|
+
<li>Document in JIRA ticket</li>
|
|
390
|
+
<li>Get approval before remediation</li>
|
|
391
|
+
</ul>' > custom-guidance.html
|
|
392
|
+
|
|
393
|
+
# Create custom appendices
|
|
394
|
+
echo '<h1>Internal Resources</h1>
|
|
395
|
+
<p>Additional company resources:</p>
|
|
396
|
+
<ul>
|
|
397
|
+
<li><a href="https://internal.company.com/security">Security Portal</a></li>
|
|
398
|
+
<li><a href="https://wiki.company.com/iam">IAM Best Practices</a></li>
|
|
399
|
+
</ul>' > custom-appendices.html
|
|
400
|
+
```
|
|
401
|
+
|
|
402
|
+
# Generate report with custom content
|
|
403
|
+
cloudsplaining scan --input-file account-data.json --output reports/
|
|
362
404
|
|
|
363
405
|
## Cheatsheet
|
|
364
406
|
|
|
@@ -1,30 +1,3 @@
|
|
|
1
|
-
Metadata-Version: 2.1
|
|
2
|
-
Name: cloudsplaining
|
|
3
|
-
Version: 0.8.0
|
|
4
|
-
Summary: AWS IAM Security Assessment tool that identifies violations of least privilege and generates a risk-prioritized HTML report.
|
|
5
|
-
Home-page: https://github.com/salesforce/cloudsplaining
|
|
6
|
-
Author: Kinnaird McQuade
|
|
7
|
-
Author-email: kinnairdm@gmail.com
|
|
8
|
-
License: UNKNOWN
|
|
9
|
-
Project-URL: Documentation, https://policy-sentry.readthedocs.io/
|
|
10
|
-
Project-URL: Example Report, https://opensource.salesforce.com/cloudsplaining
|
|
11
|
-
Project-URL: Code, https://github.com/salesforce/cloudsplaining/
|
|
12
|
-
Project-URL: Twitter, https://twitter.com/kmcquade3
|
|
13
|
-
Project-URL: Red Team Report, https://opensource.salesforce.com/policy_sentry
|
|
14
|
-
Keywords: aws iam roles policy policies privileges security
|
|
15
|
-
Platform: UNKNOWN
|
|
16
|
-
Classifier: Programming Language :: Python :: 3 :: Only
|
|
17
|
-
Classifier: Programming Language :: Python :: 3.9
|
|
18
|
-
Classifier: Programming Language :: Python :: 3.10
|
|
19
|
-
Classifier: Programming Language :: Python :: 3.11
|
|
20
|
-
Classifier: Programming Language :: Python :: 3.12
|
|
21
|
-
Classifier: Programming Language :: Python :: 3.13
|
|
22
|
-
Classifier: License :: OSI Approved :: MIT License
|
|
23
|
-
Classifier: Operating System :: OS Independent
|
|
24
|
-
Requires-Python: >=3.8
|
|
25
|
-
Description-Content-Type: text/markdown
|
|
26
|
-
License-File: LICENSE
|
|
27
|
-
|
|
28
1
|
## NOTE: This repo/project has been restored by Salesforce.
|
|
29
2
|
|
|
30
3
|
Cloudsplaining
|
|
@@ -359,6 +332,47 @@ cloudsplaining scan-multi-account \
|
|
|
359
332
|
|
|
360
333
|
> Note that if you run the above without the `--profile` flag, it will execute in the standard [AWS Credentials order of precedence](https://docs.aws.amazon.com/sdk-for-java/v1/developer-guide/credentials.html#credentials-default) (i.e., Environment variables, credentials profiles, ECS container credentials, then finally EC2 Instance Profile credentials).
|
|
361
334
|
|
|
335
|
+
## Custom Guidance and Appendices
|
|
336
|
+
|
|
337
|
+
Cloudsplaining supports customizing the Guidance and Appendices sections of the HTML report to include organization-specific security recommendations and documentation.
|
|
338
|
+
|
|
339
|
+
### How It Works
|
|
340
|
+
|
|
341
|
+
Place HTML files in your project root directory:
|
|
342
|
+
|
|
343
|
+
- `custom-guidance.html` - Custom security guidance content
|
|
344
|
+
- `custom-appendices.html` - Custom appendices content
|
|
345
|
+
|
|
346
|
+
### Behavior
|
|
347
|
+
|
|
348
|
+
- **Files don't exist**: Shows default AWS security advice
|
|
349
|
+
- **Files exist with content**: Shows your custom HTML content
|
|
350
|
+
- **Files exist but are empty**: Hides the tabs entirely
|
|
351
|
+
- **Mixed configuration**: Each tab works independently
|
|
352
|
+
|
|
353
|
+
### Example Usage
|
|
354
|
+
|
|
355
|
+
```bash
|
|
356
|
+
# Create custom guidance
|
|
357
|
+
echo '<h1>Company Security Guidelines</h1>
|
|
358
|
+
<p>Follow these organization-specific steps:</p>
|
|
359
|
+
<ul>
|
|
360
|
+
<li>Review with security team</li>
|
|
361
|
+
<li>Document in JIRA ticket</li>
|
|
362
|
+
<li>Get approval before remediation</li>
|
|
363
|
+
</ul>' > custom-guidance.html
|
|
364
|
+
|
|
365
|
+
# Create custom appendices
|
|
366
|
+
echo '<h1>Internal Resources</h1>
|
|
367
|
+
<p>Additional company resources:</p>
|
|
368
|
+
<ul>
|
|
369
|
+
<li><a href="https://internal.company.com/security">Security Portal</a></li>
|
|
370
|
+
<li><a href="https://wiki.company.com/iam">IAM Best Practices</a></li>
|
|
371
|
+
</ul>' > custom-appendices.html
|
|
372
|
+
```
|
|
373
|
+
|
|
374
|
+
# Generate report with custom content
|
|
375
|
+
cloudsplaining scan --input-file account-data.json --output reports/
|
|
362
376
|
|
|
363
377
|
## Cheatsheet
|
|
364
378
|
|
|
@@ -412,5 +426,3 @@ Try upgrading to the latest version of Cloudsplaining. This error was fixed in v
|
|
|
412
426
|
* [AWS Privilege Escalation Methods](https://github.com/RhinoSecurityLabs/AWS-IAM-Privilege-Escalation) by [Spencer Gietzen](https://twitter.com/SpenGietz) at Rhino Security Labs
|
|
413
427
|
* [Understanding Access Level Summaries within Policy Summaries](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_understand-policy-summary-access-level-summaries.html)
|
|
414
428
|
* [Leveraging next-generation blockchain-based AI across multiple service meshes to transparently automate multi-cloud IAM wizardry :mage_man:](http://kmcquade.com/rick.html)
|
|
415
|
-
|
|
416
|
-
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
# pylint: disable=missing-module-docstring
|
|
2
|
-
__version__ = "0.8.
|
|
2
|
+
__version__ = "0.8.2"
|
{cloudsplaining-0.8.0 → cloudsplaining-0.8.2}/cloudsplaining/command/create_exclusions_file.py
RENAMED
|
@@ -41,8 +41,8 @@ def create_exclusions_file(output_file: str, verbosity: int) -> None:
|
|
|
41
41
|
set_log_level(verbosity)
|
|
42
42
|
|
|
43
43
|
with open(output_file, "a", encoding="utf-8") as file_obj:
|
|
44
|
-
|
|
45
|
-
|
|
44
|
+
file_obj.write(EXCLUSIONS_TEMPLATE)
|
|
45
|
+
|
|
46
46
|
utils.print_green(f"Success! Exclusions template file written to: {output_file}")
|
|
47
47
|
print(
|
|
48
48
|
"Make sure you download your account authorization details before running the scan."
|
|
@@ -47,8 +47,8 @@ def create_multi_account_config_file(output_file: str, verbosity: int) -> None:
|
|
|
47
47
|
os.remove(output_file)
|
|
48
48
|
|
|
49
49
|
with open(output_file, "a", encoding="utf-8") as file_obj:
|
|
50
|
-
|
|
51
|
-
|
|
50
|
+
file_obj.write(MULTI_ACCOUNT_CONFIG_TEMPLATE)
|
|
51
|
+
|
|
52
52
|
utils.print_green(f"Success! Multi-account config file written to: {os.path.relpath(output_file)}")
|
|
53
53
|
print(
|
|
54
54
|
f"\nMake sure you edit the {os.path.relpath(output_file)} file and then run the scan-multi-account command, as shown below."
|
|
@@ -96,6 +96,14 @@ from cloudsplaining.shared.validation import check_authorization_details_schema
|
|
|
96
96
|
multiple=True,
|
|
97
97
|
type=click.Choice(["CRITICAL", "HIGH", "MEDIUM", "LOW", "NONE"], case_sensitive=False),
|
|
98
98
|
)
|
|
99
|
+
@click.option(
|
|
100
|
+
"-t",
|
|
101
|
+
"--flag-trust-policies",
|
|
102
|
+
required=False,
|
|
103
|
+
default=False,
|
|
104
|
+
is_flag=True,
|
|
105
|
+
help="Flag risky trust policies in roles.",
|
|
106
|
+
)
|
|
99
107
|
def scan(
|
|
100
108
|
input_file: str,
|
|
101
109
|
exclusions_file: str,
|
|
@@ -105,6 +113,7 @@ def scan(
|
|
|
105
113
|
flag_all_risky_actions: bool,
|
|
106
114
|
verbosity: int,
|
|
107
115
|
severity: list[str],
|
|
116
|
+
flag_trust_policies: bool,
|
|
108
117
|
) -> None: # pragma: no cover
|
|
109
118
|
"""
|
|
110
119
|
Given the path to account authorization details files and the exclusions config file, scan all inline and
|
|
@@ -142,6 +151,7 @@ def scan(
|
|
|
142
151
|
minimize=minimize,
|
|
143
152
|
flag_conditional_statements=flag_conditional_statements,
|
|
144
153
|
flag_resource_arn_statements=flag_resource_arn_statements,
|
|
154
|
+
flag_trust_policies=flag_trust_policies,
|
|
145
155
|
severity=severity,
|
|
146
156
|
)
|
|
147
157
|
html_output_file = os.path.join(output, f"iam-report-{account_name}.html")
|
|
@@ -207,6 +217,7 @@ def scan_account_authorization_details(
|
|
|
207
217
|
return_json_results: Literal[True],
|
|
208
218
|
flag_conditional_statements: bool = ...,
|
|
209
219
|
flag_resource_arn_statements: bool = ...,
|
|
220
|
+
flag_trust_policies: bool = ...,
|
|
210
221
|
severity: list[str] | None = ...,
|
|
211
222
|
) -> dict[str, Any]: ...
|
|
212
223
|
|
|
@@ -222,6 +233,7 @@ def scan_account_authorization_details(
|
|
|
222
233
|
return_json_results: Literal[False] = ...,
|
|
223
234
|
flag_conditional_statements: bool = ...,
|
|
224
235
|
flag_resource_arn_statements: bool = ...,
|
|
236
|
+
flag_trust_policies: bool = ...,
|
|
225
237
|
severity: list[str] | None = ...,
|
|
226
238
|
) -> str: ...
|
|
227
239
|
|
|
@@ -236,6 +248,7 @@ def scan_account_authorization_details(
|
|
|
236
248
|
return_json_results: bool = False,
|
|
237
249
|
flag_conditional_statements: bool = False,
|
|
238
250
|
flag_resource_arn_statements: bool = False,
|
|
251
|
+
flag_trust_policies: bool = False,
|
|
239
252
|
severity: list[str] | None = None,
|
|
240
253
|
) -> str | dict[str, Any]: # pragma: no cover
|
|
241
254
|
"""
|
|
@@ -250,6 +263,7 @@ def scan_account_authorization_details(
|
|
|
250
263
|
exclusions=exclusions,
|
|
251
264
|
flag_conditional_statements=flag_conditional_statements,
|
|
252
265
|
flag_resource_arn_statements=flag_resource_arn_statements,
|
|
266
|
+
flag_trust_policies=flag_trust_policies,
|
|
253
267
|
severity=severity,
|
|
254
268
|
)
|
|
255
269
|
results = authorization_details.results
|
|
@@ -120,6 +120,14 @@ class MultiAccountConfig:
|
|
|
120
120
|
multiple=True,
|
|
121
121
|
type=click.Choice(["CRITICAL", "HIGH", "MEDIUM", "LOW", "NONE"], case_sensitive=False),
|
|
122
122
|
)
|
|
123
|
+
@click.option(
|
|
124
|
+
"-t",
|
|
125
|
+
"--flag-trust-policies",
|
|
126
|
+
required=False,
|
|
127
|
+
default=False,
|
|
128
|
+
is_flag=True,
|
|
129
|
+
help="Flag risky trust policies in roles.",
|
|
130
|
+
)
|
|
123
131
|
def scan_multi_account(
|
|
124
132
|
config_file: str,
|
|
125
133
|
profile: str,
|
|
@@ -131,6 +139,7 @@ def scan_multi_account(
|
|
|
131
139
|
flag_all_risky_actions: bool,
|
|
132
140
|
verbosity: int,
|
|
133
141
|
severity: list[str],
|
|
142
|
+
flag_trust_policies: bool,
|
|
134
143
|
) -> None:
|
|
135
144
|
"""Scan multiple accounts via AssumeRole"""
|
|
136
145
|
set_log_level(verbosity)
|
|
@@ -160,6 +169,7 @@ def scan_multi_account(
|
|
|
160
169
|
severity=severity,
|
|
161
170
|
flag_conditional_statements=flag_conditional_statements,
|
|
162
171
|
flag_resource_arn_statements=flag_resource_arn_statements,
|
|
172
|
+
flag_trust_policies=flag_trust_policies,
|
|
163
173
|
)
|
|
164
174
|
|
|
165
175
|
|
|
@@ -174,6 +184,7 @@ def scan_accounts(
|
|
|
174
184
|
severity: list[str] | None = None,
|
|
175
185
|
flag_conditional_statements: bool = False,
|
|
176
186
|
flag_resource_arn_statements: bool = False,
|
|
187
|
+
flag_trust_policies: bool = False,
|
|
177
188
|
) -> None:
|
|
178
189
|
"""Use this method as a library to scan multiple accounts"""
|
|
179
190
|
# TODO: Speed improvements? Multithreading? This currently runs sequentially.
|
|
@@ -187,6 +198,7 @@ def scan_accounts(
|
|
|
187
198
|
severity=severity,
|
|
188
199
|
flag_conditional_statements=flag_conditional_statements,
|
|
189
200
|
flag_resource_arn_statements=flag_resource_arn_statements,
|
|
201
|
+
flag_trust_policies=flag_trust_policies,
|
|
190
202
|
)
|
|
191
203
|
html_report = HTMLReport(
|
|
192
204
|
account_id=target_account_id,
|
|
@@ -233,6 +245,7 @@ def scan_account(
|
|
|
233
245
|
severity: list[str] | None = None,
|
|
234
246
|
flag_conditional_statements: bool = False,
|
|
235
247
|
flag_resource_arn_statements: bool = False,
|
|
248
|
+
flag_trust_policies: bool = False,
|
|
236
249
|
) -> dict[str, dict[str, Any]]:
|
|
237
250
|
"""Scan a target account in one shot"""
|
|
238
251
|
account_authorization_details = download_account_authorization_details(
|
|
@@ -247,6 +260,7 @@ def scan_account(
|
|
|
247
260
|
severity=severity,
|
|
248
261
|
flag_conditional_statements=flag_conditional_statements,
|
|
249
262
|
flag_resource_arn_statements=flag_resource_arn_statements,
|
|
263
|
+
flag_trust_policies=flag_trust_policies,
|
|
250
264
|
)
|
|
251
265
|
results = authorization_details.results
|
|
252
266
|
return results
|