cloudsplaining 0.6.3__tar.gz → 0.7.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 (127) hide show
  1. cloudsplaining-0.7.0/LICENSE +12 -0
  2. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/PKG-INFO +3 -3
  3. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/cloudsplaining/__init__.py +10 -11
  4. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/cloudsplaining/bin/cli.py +3 -1
  5. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/cloudsplaining/bin/version.py +1 -1
  6. cloudsplaining-0.7.0/cloudsplaining/command/__init__.py +11 -0
  7. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/cloudsplaining/command/create_exclusions_file.py +15 -7
  8. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/cloudsplaining/command/create_multi_account_config_file.py +17 -10
  9. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/cloudsplaining/command/download.py +33 -22
  10. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/cloudsplaining/command/expand_policy.py +12 -5
  11. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/cloudsplaining/command/scan.py +122 -59
  12. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/cloudsplaining/command/scan_multi_account.py +121 -79
  13. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/cloudsplaining/command/scan_policy_file.py +54 -84
  14. cloudsplaining-0.7.0/cloudsplaining/output/dist/js/index.js +63 -0
  15. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/cloudsplaining/output/policy_finding.py +46 -49
  16. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/cloudsplaining/output/report.py +17 -12
  17. cloudsplaining-0.7.0/cloudsplaining/output/src/components/Summary.vue +167 -0
  18. cloudsplaining-0.7.0/cloudsplaining/output/src/components/charts/SummaryFindings.vue +124 -0
  19. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/cloudsplaining/scan/assume_role_policy_document.py +7 -8
  20. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/cloudsplaining/scan/authorization_details.py +17 -25
  21. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/cloudsplaining/scan/group_details.py +40 -59
  22. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/cloudsplaining/scan/inline_policy.py +83 -92
  23. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/cloudsplaining/scan/managed_policy_detail.py +100 -122
  24. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/cloudsplaining/scan/policy_document.py +58 -85
  25. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/cloudsplaining/scan/resource_policy_document.py +8 -19
  26. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/cloudsplaining/scan/role_details.py +45 -64
  27. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/cloudsplaining/scan/statement_detail.py +49 -76
  28. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/cloudsplaining/scan/user_details.py +42 -61
  29. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/cloudsplaining/shared/aws_login.py +14 -21
  30. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/cloudsplaining/shared/constants.py +6 -5
  31. cloudsplaining-0.7.0/cloudsplaining/shared/exceptions.py +2 -0
  32. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/cloudsplaining/shared/exclusions.py +26 -25
  33. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/cloudsplaining/shared/utils.py +19 -27
  34. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/cloudsplaining/shared/validation.py +9 -8
  35. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/cloudsplaining.egg-info/PKG-INFO +3 -3
  36. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/cloudsplaining.egg-info/SOURCES.txt +2 -1
  37. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/cloudsplaining.egg-info/requires.txt +1 -1
  38. cloudsplaining-0.7.0/pyproject.toml +79 -0
  39. cloudsplaining-0.7.0/setup.cfg +4 -0
  40. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/setup.py +31 -43
  41. cloudsplaining-0.6.3/cloudsplaining/command/__init__.py +0 -8
  42. cloudsplaining-0.6.3/cloudsplaining/output/dist/js/index.js +0 -334
  43. cloudsplaining-0.6.3/cloudsplaining/output/src/components/Summary.vue +0 -164
  44. cloudsplaining-0.6.3/cloudsplaining/output/src/components/charts/SummaryFindings.vue +0 -108
  45. cloudsplaining-0.6.3/cloudsplaining/shared/exceptions.py +0 -3
  46. cloudsplaining-0.6.3/setup.cfg +0 -38
  47. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/MANIFEST.in +0 -0
  48. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/README.md +0 -0
  49. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/cloudsplaining/bin/__init__.py +0 -0
  50. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/cloudsplaining/output/__init__.py +0 -0
  51. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/cloudsplaining/output/dist/index.html +0 -0
  52. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/cloudsplaining/output/dist/js/chunk-vendors.js +0 -0
  53. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/cloudsplaining/output/public/index.html +0 -0
  54. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/cloudsplaining/output/src/App.vue +0 -0
  55. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/cloudsplaining/output/src/assets/1-overview.md +0 -0
  56. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/cloudsplaining/output/src/assets/2-triage-guidance.md +0 -0
  57. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/cloudsplaining/output/src/assets/3-remediation-guidance.md +0 -0
  58. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/cloudsplaining/output/src/assets/4-validation.md +0 -0
  59. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/cloudsplaining/output/src/assets/definition-assumable-by-compute-service.md +0 -0
  60. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/cloudsplaining/output/src/assets/definition-credentials-exposure.md +0 -0
  61. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/cloudsplaining/output/src/assets/definition-data-exfiltration.md +0 -0
  62. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/cloudsplaining/output/src/assets/definition-infrastructure-modification.md +0 -0
  63. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/cloudsplaining/output/src/assets/definition-privilege-escalation.md +0 -0
  64. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/cloudsplaining/output/src/assets/definition-resource-exposure.md +0 -0
  65. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/cloudsplaining/output/src/assets/definition-service-wildcard.md +0 -0
  66. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/cloudsplaining/output/src/assets/glossary.md +0 -0
  67. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/cloudsplaining/output/src/assets/how-do-i-validate-results.md +0 -0
  68. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/cloudsplaining/output/src/assets/identifying-false-positives.md +0 -0
  69. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/cloudsplaining/output/src/assets/logo.png +0 -0
  70. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/cloudsplaining/output/src/assets/summary.md +0 -0
  71. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/cloudsplaining/output/src/assets/what-should-i-do.md +0 -0
  72. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/cloudsplaining/output/src/components/Appendix.vue +0 -0
  73. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/cloudsplaining/output/src/components/Button.vue +0 -0
  74. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/cloudsplaining/output/src/components/Glossary.vue +0 -0
  75. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/cloudsplaining/output/src/components/Guidance.vue +0 -0
  76. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/cloudsplaining/output/src/components/InlinePolicies.vue +0 -0
  77. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/cloudsplaining/output/src/components/LinkToFinding.vue +0 -0
  78. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/cloudsplaining/output/src/components/ManagedPolicies.vue +0 -0
  79. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/cloudsplaining/output/src/components/PolicyTable.vue +0 -0
  80. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/cloudsplaining/output/src/components/Principals.vue +0 -0
  81. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/cloudsplaining/output/src/components/ReportMetadata.vue +0 -0
  82. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/cloudsplaining/output/src/components/TaskTable.vue +0 -0
  83. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/cloudsplaining/output/src/components/finding/AssumeRoleDetails.vue +0 -0
  84. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/cloudsplaining/output/src/components/finding/FindingCard.vue +0 -0
  85. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/cloudsplaining/output/src/components/finding/FindingDetails.vue +0 -0
  86. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/cloudsplaining/output/src/components/finding/PolicyDocumentDetails.vue +0 -0
  87. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/cloudsplaining/output/src/components/finding/PrivilegeEscalationDetails.vue +0 -0
  88. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/cloudsplaining/output/src/components/finding/PrivilegeEscalationFormat.vue +0 -0
  89. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/cloudsplaining/output/src/components/finding/RiskAlertIndicators.vue +0 -0
  90. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/cloudsplaining/output/src/components/finding/StandardRiskDetails.vue +0 -0
  91. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/cloudsplaining/output/src/components/principals/PrincipalMetadata.vue +0 -0
  92. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/cloudsplaining/output/src/components/principals/RisksPerPrincipal.vue +0 -0
  93. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/cloudsplaining/output/src/main.js +0 -0
  94. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/cloudsplaining/output/src/routes/routes.js +0 -0
  95. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/cloudsplaining/output/src/sampleData.js +0 -0
  96. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/cloudsplaining/output/src/test/groups-test.js +0 -0
  97. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/cloudsplaining/output/src/test/inline-policies-test.js +0 -0
  98. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/cloudsplaining/output/src/test/managed-policies-test.js +0 -0
  99. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/cloudsplaining/output/src/test/other-test.js +0 -0
  100. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/cloudsplaining/output/src/test/principals-test.js +0 -0
  101. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/cloudsplaining/output/src/test/roles-test.js +0 -0
  102. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/cloudsplaining/output/src/test/task-table-test.js +0 -0
  103. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/cloudsplaining/output/src/util/glossary.js +0 -0
  104. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/cloudsplaining/output/src/util/groups.js +0 -0
  105. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/cloudsplaining/output/src/util/inline-policies.js +0 -0
  106. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/cloudsplaining/output/src/util/managed-policies.js +0 -0
  107. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/cloudsplaining/output/src/util/other.js +0 -0
  108. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/cloudsplaining/output/src/util/principals.js +0 -0
  109. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/cloudsplaining/output/src/util/roles.js +0 -0
  110. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/cloudsplaining/output/src/util/task-table.js +0 -0
  111. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/cloudsplaining/output/src/views/Appendices.vue +0 -0
  112. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/cloudsplaining/output/src/views/AwsPolicies.vue +0 -0
  113. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/cloudsplaining/output/src/views/CustomerPolicies.vue +0 -0
  114. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/cloudsplaining/output/src/views/Guidance.vue +0 -0
  115. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/cloudsplaining/output/src/views/IamPrincipals.vue +0 -0
  116. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/cloudsplaining/output/src/views/InlinePolicies.vue +0 -0
  117. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/cloudsplaining/output/src/views/Summary.vue +0 -0
  118. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/cloudsplaining/output/template.html +0 -0
  119. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/cloudsplaining/py.typed +0 -0
  120. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/cloudsplaining/scan/__init__.py +0 -0
  121. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/cloudsplaining/shared/__init__.py +0 -0
  122. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/cloudsplaining/shared/default-exclusions.yml +0 -0
  123. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/cloudsplaining/shared/multi-account-config.yml +0 -0
  124. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/cloudsplaining.egg-info/dependency_links.txt +0 -0
  125. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/cloudsplaining.egg-info/entry_points.txt +0 -0
  126. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/cloudsplaining.egg-info/top_level.txt +0 -0
  127. {cloudsplaining-0.6.3 → cloudsplaining-0.7.0}/cloudsplaining.egg-info/zip-safe +0 -0
@@ -0,0 +1,12 @@
1
+ Copyright (c) 2020, Salesforce.com, Inc.
2
+ All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
5
+
6
+ * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7
+
8
+ * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
9
+
10
+ * Neither the name of Salesforce.com nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
11
+
12
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: cloudsplaining
3
- Version: 0.6.3
3
+ Version: 0.7.0
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
@@ -402,13 +402,13 @@ Description: ## NOTE: This repo/project has been restored by Salesforce.
402
402
  Keywords: aws iam roles policy policies privileges security
403
403
  Platform: UNKNOWN
404
404
  Classifier: Programming Language :: Python :: 3 :: Only
405
- Classifier: Programming Language :: Python :: 3.7
406
405
  Classifier: Programming Language :: Python :: 3.8
407
406
  Classifier: Programming Language :: Python :: 3.9
408
407
  Classifier: Programming Language :: Python :: 3.10
409
408
  Classifier: Programming Language :: Python :: 3.11
410
409
  Classifier: Programming Language :: Python :: 3.12
410
+ Classifier: Programming Language :: Python :: 3.13
411
411
  Classifier: License :: OSI Approved :: MIT License
412
412
  Classifier: Operating System :: OS Independent
413
- Requires-Python: >=3.6
413
+ Requires-Python: >=3.8
414
414
  Description-Content-Type: text/markdown
@@ -1,16 +1,15 @@
1
1
  # pylint: disable=missing-module-docstring
2
+ from __future__ import annotations
3
+
2
4
  import logging
3
5
  import sys
4
6
 
5
7
  # Set default logging handler to avoid "No handler found" warnings.
6
- from logging import NullHandler
7
-
8
+ # from logging import NullHandler
8
9
  # logging.getLogger(__name__).addHandler(NullHandler())
9
10
  # Uncomment to get the full debug logs.
10
11
  # 2020-10-06 10:04:17,200 - root - DEBUG - Leveraging the bundled IAM Definition.
11
12
  # Need to figure out how to get click_log to do this for me.
12
- from typing import Union, Optional
13
-
14
13
  logger = logging.getLogger(__name__)
15
14
  logger.setLevel(logging.WARNING)
16
15
  handler = logging.StreamHandler(sys.stdout)
@@ -23,8 +22,8 @@ logger.addHandler(handler)
23
22
  name = "cloudsplaining" # pylint: disable=invalid-name
24
23
 
25
24
 
26
- def change_log_level(log_level: Union[int, str]) -> None:
27
- """"Change log level of module logger"""
25
+ def change_log_level(log_level: int | str) -> None:
26
+ """ "Change log level of module logger"""
28
27
  logger.setLevel(log_level)
29
28
 
30
29
 
@@ -32,7 +31,7 @@ def change_log_level(log_level: Union[int, str]) -> None:
32
31
  def set_stream_logger(
33
32
  name: str = "cloudsplaining",
34
33
  level: int = logging.DEBUG,
35
- format_string: Optional[str] = None,
34
+ format_string: str | None = None,
36
35
  ) -> None:
37
36
  """
38
37
  Add a stream handler for the given name and level to the logging module.
@@ -71,10 +70,10 @@ def set_log_level(verbose: int) -> None:
71
70
  :return:
72
71
  """
73
72
  if verbose == 1:
74
- set_stream_logger(level=getattr(logging, "WARNING"))
73
+ set_stream_logger(level=logging.WARNING)
75
74
  elif verbose == 2:
76
- set_stream_logger(level=getattr(logging, "INFO"))
75
+ set_stream_logger(level=logging.INFO)
77
76
  elif verbose >= 3:
78
- set_stream_logger(level=getattr(logging, "DEBUG"))
77
+ set_stream_logger(level=logging.DEBUG)
79
78
  else:
80
- set_stream_logger(level=getattr(logging, "CRITICAL"))
79
+ set_stream_logger(level=logging.CRITICAL)
@@ -5,9 +5,11 @@
5
5
  # For full license text, see the LICENSE file in the repo root
6
6
  # or https://opensource.org/licenses/BSD-3-Clause
7
7
  """
8
- Cloudsplaining is an AWS IAM Assessment tool that identifies violations of least privilege and generates a risk-prioritized HTML report with a triage worksheet.
8
+ Cloudsplaining is an AWS IAM Assessment tool that identifies violations of least privilege and generates a risk-prioritized HTML report with a triage worksheet.
9
9
  """
10
+
10
11
  import click
12
+
11
13
  from cloudsplaining import command
12
14
  from cloudsplaining.bin.version import __version__
13
15
 
@@ -1,2 +1,2 @@
1
1
  # pylint: disable=missing-module-docstring
2
- __version__ = '0.6.3'
2
+ __version__ = "0.7.0"
@@ -0,0 +1,11 @@
1
+ # ruff: noqa: F401
2
+ # pylint: disable=missing-module-docstring
3
+ from cloudsplaining.command import (
4
+ create_exclusions_file,
5
+ create_multi_account_config_file,
6
+ download,
7
+ expand_policy,
8
+ scan,
9
+ scan_multi_account,
10
+ scan_policy_file,
11
+ )
@@ -2,17 +2,20 @@
2
2
  Create YML Template files for the exclusions template command.
3
3
  This way, users don't have to remember exactly how to phrase the yaml files, since this command creates it for them.
4
4
  """
5
+
5
6
  # Copyright (c) 2020, salesforce.com, inc.
6
7
  # All rights reserved.
7
8
  # Licensed under the BSD 3-Clause license.
8
9
  # For full license text, see the LICENSE file in the repo root
9
10
  # or https://opensource.org/licenses/BSD-3-Clause
10
- import os
11
11
  import logging
12
+ import os
13
+
12
14
  import click
13
- from cloudsplaining.shared.constants import EXCLUSIONS_TEMPLATE
15
+
14
16
  from cloudsplaining import set_log_level
15
17
  from cloudsplaining.shared import utils
18
+ from cloudsplaining.shared.constants import EXCLUSIONS_TEMPLATE
16
19
 
17
20
  logger = logging.getLogger(__name__)
18
21
 
@@ -21,7 +24,14 @@ logger = logging.getLogger(__name__)
21
24
  context_settings=dict(max_content_width=160),
22
25
  short_help="Creates a YML file to be used as a custom exclusions template",
23
26
  )
24
- @click.option("-o", "--output-file", type=click.Path(exists=False), default=os.path.join(os.getcwd(), "exclusions.yml"), required=True, help="Relative path to output file where we want to store the exclusions template.")
27
+ @click.option(
28
+ "-o",
29
+ "--output-file",
30
+ type=click.Path(exists=False),
31
+ default=os.path.join(os.getcwd(), "exclusions.yml"),
32
+ required=True,
33
+ help="Relative path to output file where we want to store the exclusions template.",
34
+ )
25
35
  @click.option("--verbose", "-v", "verbosity", count=True)
26
36
  def create_exclusions_file(output_file: str, verbosity: int) -> None:
27
37
  """
@@ -30,7 +40,7 @@ def create_exclusions_file(output_file: str, verbosity: int) -> None:
30
40
  """
31
41
  set_log_level(verbosity)
32
42
 
33
- with open(output_file, "a") as file_obj:
43
+ with open(output_file, "a", encoding="utf-8") as file_obj:
34
44
  for line in EXCLUSIONS_TEMPLATE:
35
45
  file_obj.write(line)
36
46
  utils.print_green(f"Success! Exclusions template file written to: {output_file}")
@@ -40,6 +50,4 @@ def create_exclusions_file(output_file: str, verbosity: int) -> None:
40
50
  )
41
51
  print("\tcloudsplaining download")
42
52
  print("You can use this with the scan command as shown below: ")
43
- print(
44
- "\tcloudsplaining scan --exclusions-file exclusions.yml --input-file default.json"
45
- )
53
+ print("\tcloudsplaining scan --exclusions-file exclusions.yml --input-file default.json")
@@ -2,17 +2,20 @@
2
2
  Create YML Template files for the exclusions template command.
3
3
  This way, users don't have to remember exactly how to phrase the yaml files, since this command creates it for them.
4
4
  """
5
+
5
6
  # Copyright (c) 2020, salesforce.com, inc.
6
7
  # All rights reserved.
7
8
  # Licensed under the BSD 3-Clause license.
8
9
  # For full license text, see the LICENSE file in the repo root
9
10
  # or https://opensource.org/licenses/BSD-3-Clause
10
- import os
11
11
  import logging
12
+ import os
13
+
12
14
  import click
13
- from cloudsplaining.shared.constants import MULTI_ACCOUNT_CONFIG_TEMPLATE
15
+
14
16
  from cloudsplaining import set_log_level
15
17
  from cloudsplaining.shared import utils
18
+ from cloudsplaining.shared.constants import MULTI_ACCOUNT_CONFIG_TEMPLATE
16
19
 
17
20
  logger = logging.getLogger(__name__)
18
21
  OK_GREEN = "\033[92m"
@@ -23,7 +26,15 @@ END = "\033[0m"
23
26
  context_settings=dict(max_content_width=160),
24
27
  short_help="Creates a YML file to be used for multi-account scanning",
25
28
  )
26
- @click.option("-o", "--output-file", "output_file", type=click.Path(exists=False), default=os.path.join(os.getcwd(), "multi-account-config.yml"), required=True, help="Relative path to output file where we want to store the multi account config template.")
29
+ @click.option(
30
+ "-o",
31
+ "--output-file",
32
+ "output_file",
33
+ type=click.Path(exists=False),
34
+ default=os.path.join(os.getcwd(), "multi-account-config.yml"),
35
+ required=True,
36
+ help="Relative path to output file where we want to store the multi account config template.",
37
+ )
27
38
  @click.option("-v", "--verbose", "verbosity", help="Log verbosity level.", count=True)
28
39
  def create_multi_account_config_file(output_file: str, verbosity: int) -> None:
29
40
  """
@@ -32,17 +43,13 @@ def create_multi_account_config_file(output_file: str, verbosity: int) -> None:
32
43
  set_log_level(verbosity)
33
44
 
34
45
  if os.path.exists(output_file):
35
- logger.debug(
36
- "%s exists. Removing the file and replacing its contents.", output_file
37
- )
46
+ logger.debug("%s exists. Removing the file and replacing its contents.", output_file)
38
47
  os.remove(output_file)
39
48
 
40
- with open(output_file, "a") as file_obj:
49
+ with open(output_file, "a", encoding="utf-8") as file_obj:
41
50
  for line in MULTI_ACCOUNT_CONFIG_TEMPLATE:
42
51
  file_obj.write(line)
43
- utils.print_green(
44
- f"Success! Multi-account config file written to: {os.path.relpath(output_file)}"
45
- )
52
+ utils.print_green(f"Success! Multi-account config file written to: {os.path.relpath(output_file)}")
46
53
  print(
47
54
  f"\nMake sure you edit the {os.path.relpath(output_file)} file and then run the scan-multi-account command, as shown below."
48
55
  )
@@ -1,5 +1,6 @@
1
1
  """Runs aws iam get-authorization-details on all accounts specified in the aws credentials file, and stores them in
2
- account-alias.json """
2
+ account-alias.json"""
3
+
3
4
  # Copyright (c) 2020, salesforce.com, inc.
4
5
  # All rights reserved.
5
6
  # Licensed under the BSD 3-Clause license.
@@ -10,7 +11,7 @@ from __future__ import annotations
10
11
  import json
11
12
  import logging
12
13
  import os
13
- from typing import Dict, List, Any, TYPE_CHECKING
14
+ from typing import TYPE_CHECKING, Any
14
15
 
15
16
  import boto3
16
17
  import click
@@ -28,13 +29,29 @@ logger = logging.getLogger(__name__)
28
29
  short_help="Runs aws iam get-authorization-details on all accounts specified in the aws credentials "
29
30
  "file, and stores them in account-alias.json"
30
31
  )
31
- @click.option("-p", "--profile", type=str, required=False, envvar="AWS_DEFAULT_PROFILE", help="Specify 'all' to authenticate to AWS and scan from *all* AWS credentials profiles. Specify a non-default profile here. Defaults to the 'default' profile.")
32
- @click.option("-o", "--output", type=click.Path(exists=True), default=os.getcwd(), help="Path to store the output. Defaults to current directory.")
33
- @click.option("--include-non-default-policy-versions", is_flag=True, default=False, help="When downloading AWS managed policy documents, also include the non-default policy versions. Note that this will dramatically increase the size of the downloaded file.")
32
+ @click.option(
33
+ "-p",
34
+ "--profile",
35
+ type=str,
36
+ required=False,
37
+ envvar="AWS_DEFAULT_PROFILE",
38
+ help="Specify 'all' to authenticate to AWS and scan from *all* AWS credentials profiles. Specify a non-default profile here. Defaults to the 'default' profile.",
39
+ )
40
+ @click.option(
41
+ "-o",
42
+ "--output",
43
+ type=click.Path(exists=True),
44
+ default=os.getcwd(),
45
+ help="Path to store the output. Defaults to current directory.",
46
+ )
47
+ @click.option(
48
+ "--include-non-default-policy-versions",
49
+ is_flag=True,
50
+ default=False,
51
+ help="When downloading AWS managed policy documents, also include the non-default policy versions. Note that this will dramatically increase the size of the downloaded file.",
52
+ )
34
53
  @click.option("-v", "--verbose", "verbosity", help="Log verbosity level.", count=True)
35
- def download(
36
- profile: str, output: str, include_non_default_policy_versions: bool, verbosity: int
37
- ) -> int:
54
+ def download(profile: str, output: str, include_non_default_policy_versions: bool, verbosity: int) -> int:
38
55
  """
39
56
  Runs aws iam get-authorization-details on all accounts specified in the aws credentials file, and stores them in
40
57
  account-alias.json
@@ -50,10 +67,8 @@ def download(
50
67
  else:
51
68
  output_filename = os.path.join(output, "default.json")
52
69
 
53
- results = get_account_authorization_details(
54
- session_data, include_non_default_policy_versions
55
- )
56
- with open(output_filename, "w") as f:
70
+ results = get_account_authorization_details(session_data, include_non_default_policy_versions)
71
+ with open(output_filename, "w", encoding="utf-8") as f:
57
72
  json.dump(results, f, indent=4, default=str)
58
73
  # output_filename.write_text(json.dumps(results, indent=4, default=str))
59
74
  print(f"Saved results to {output_filename}")
@@ -61,14 +76,14 @@ def download(
61
76
 
62
77
 
63
78
  def get_account_authorization_details(
64
- session_data: Dict[str, str], include_non_default_policy_versions: bool
65
- ) -> Dict[str, List[Any]]:
79
+ session_data: dict[str, str], include_non_default_policy_versions: bool
80
+ ) -> dict[str, list[Any]]:
66
81
  """Runs aws-iam-get-account-authorization-details"""
67
- session = boto3.Session(**session_data) # type:ignore[arg-type] # dynamically constructed
82
+ session = boto3.Session(**session_data) # type:ignore[arg-type]
68
83
  config = Config(connect_timeout=5, retries={"max_attempts": 10})
69
84
  iam_client: IAMClient = session.client("iam", config=config)
70
85
 
71
- results: Dict[str, List[Any]] = {
86
+ results: dict[str, list[Any]] = {
72
87
  "UserDetailList": [],
73
88
  "GroupDetailList": [],
74
89
  "RoleDetailList": [],
@@ -100,9 +115,7 @@ def get_account_authorization_details(
100
115
  else:
101
116
  policy_version_list = []
102
117
  for policy_version in policy.get("PolicyVersionList") or []:
103
- if policy_version.get("VersionId") == policy.get(
104
- "DefaultVersionId"
105
- ):
118
+ if policy_version.get("VersionId") == policy.get("DefaultVersionId"):
106
119
  policy_version_list.append(policy_version)
107
120
  break
108
121
  entry = {
@@ -112,9 +125,7 @@ def get_account_authorization_details(
112
125
  "Path": policy.get("Path"),
113
126
  "DefaultVersionId": policy.get("DefaultVersionId"),
114
127
  "AttachmentCount": policy.get("AttachmentCount"),
115
- "PermissionsBoundaryUsageCount": policy.get(
116
- "PermissionsBoundaryUsageCount"
117
- ),
128
+ "PermissionsBoundaryUsageCount": policy.get("PermissionsBoundaryUsageCount"),
118
129
  "IsAttachable": policy.get("IsAttachable"),
119
130
  "CreateDate": policy.get("CreateDate"),
120
131
  "UpdateDate": policy.get("UpdateDate"),
@@ -1,24 +1,31 @@
1
1
  """
2
2
  Expands the wildcards (*) on an IAM policy file so it is easier for a human to understand. Example: s3:g* vs s3:GetObject, s3:GetObjectAcl, etc.
3
3
  """
4
+
4
5
  # Copyright (c) 2020, salesforce.com, inc.
5
6
  # All rights reserved.
6
7
  # Licensed under the BSD 3-Clause license.
7
8
  # For full license text, see the LICENSE file in the repo rootgit pus
8
9
  # or https://opensource.org/licenses/BSD-3-Clause
9
- import logging
10
10
  import json
11
+ import logging
12
+
11
13
  import click
12
14
  from policy_sentry.analysis.expand import get_expanded_policy
15
+
13
16
  from cloudsplaining import set_log_level
14
17
 
15
18
  logger = logging.getLogger(__name__)
16
19
 
17
20
 
18
- @click.command(
19
- short_help="Expand the * Actions in IAM policy files to improve readability"
21
+ @click.command(short_help="Expand the * Actions in IAM policy files to improve readability")
22
+ @click.option(
23
+ "-i",
24
+ "--input-file",
25
+ type=click.Path(exists=True),
26
+ required=True,
27
+ help="Path to the JSON policy file.",
20
28
  )
21
- @click.option("-i", "--input-file", type=click.Path(exists=True), required=True, help="Path to the JSON policy file.")
22
29
  @click.option("-v", "--verbose", "verbosity", help="Log verbosity level.", count=True)
23
30
  def expand_policy(input_file: str, verbosity: int) -> None:
24
31
  """
@@ -26,7 +33,7 @@ def expand_policy(input_file: str, verbosity: int) -> None:
26
33
  """
27
34
  set_log_level(verbosity)
28
35
 
29
- with open(input_file) as json_file:
36
+ with open(input_file, encoding="utf-8") as json_file:
30
37
  logger.debug(f"Opening {input_file}")
31
38
  data = json.load(json_file)
32
39
  policy = get_expanded_policy(data)