diff --git a/.github/workflows/nodejs-test.yml b/.github/workflows/nodejs-test.yml index 092e55b3..feeef514 100644 --- a/.github/workflows/nodejs-test.yml +++ b/.github/workflows/nodejs-test.yml @@ -8,15 +8,15 @@ on: - master pull_request: +permissions: + contents: read + jobs: build: - runs-on: ubuntu-latest - strategy: matrix: node-version: ['18', '20'] - steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: Use Node.js ${{ matrix.node-version }} diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index d534e8c3..d757e467 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -7,6 +7,12 @@ on: types: [published] workflow_dispatch: +permissions: + contents: read + +env: + MIN_PYTHON_VERSION: "3.9" + jobs: test: runs-on: ubuntu-latest @@ -16,7 +22,7 @@ jobs: - name: Setup Python uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b # v5.3.0 with: - python-version: '3.8' + python-version: ${{ env.MIN_PYTHON_VERSION }} - name: Install dependencies run: | @@ -39,7 +45,7 @@ jobs: - name: Set up Python uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b # v5.3.0 with: - python-version: '3.8' + python-version: ${{ env.MIN_PYTHON_VERSION }} - name: Install dependencies run: | @@ -61,12 +67,14 @@ jobs: update-brew: needs: publish-package runs-on: ubuntu-latest + permissions: + contents: write steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: Set up Python uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b # v5.3.0 with: - python-version: '3.8' + python-version: ${{ env.MIN_PYTHON_VERSION }} - name: publish brew run: | sleep 5m @@ -87,6 +95,8 @@ jobs: bump-version: runs-on: ubuntu-latest needs: update-brew + permissions: + contents: write steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: diff --git a/.github/workflows/python-dependency-updater.yml b/.github/workflows/python-dependency-updater.yml deleted file mode 100644 index a535dd66..00000000 --- a/.github/workflows/python-dependency-updater.yml +++ /dev/null @@ -1,25 +0,0 @@ -name: python-dependency-updater - -on: - # Run on the first day of the month - schedule: - - cron: '0 0 1 * *' - workflow_dispatch: - -jobs: - python-dependency-updater: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - - name: Setup Python - uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b # v5.3.0 - with: - python-version: '3.8' - - - name: Run Pyup.io Dependency updater - run: | - pip install pyupio - pip install -r requirements.txt - default_branch=$(git remote show origin | grep 'HEAD branch' | cut -d' ' -f5) - pyup --provider github --provider_url https://api.github.com --repo="$GITHUB_REPOSITORY" --user-token=${{ secrets.PYUP_GITHUB_ACCESS_TOKEN }} --branch "$default_branch" --initial diff --git a/.github/workflows/security.yml b/.github/workflows/security.yml index 2ca5cc0e..3e9f87ad 100644 --- a/.github/workflows/security.yml +++ b/.github/workflows/security.yml @@ -7,6 +7,10 @@ on: push: branches: - master + +permissions: + contents: read + jobs: detect-secrets: runs-on: ubuntu-latest diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 316719a4..63cff6a9 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -8,6 +8,12 @@ on: - master pull_request: +permissions: + contents: read + +env: + MIN_PYTHON_VERSION: "3.9" + jobs: pre-commit: runs-on: ubuntu-latest @@ -15,7 +21,7 @@ jobs: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b # v5.3.0 with: - python-version: '3.8' # needed for 'pyupgrade' + python-version: ${{ env.MIN_PYTHON_VERSION }} - uses: pre-commit/action@2c7b3805fd2a0fd8c1884dcaebf91fc102a13ecd # v3.0.1 ci: @@ -28,7 +34,7 @@ jobs: - name: Setup Python uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b # v5.3.0 with: - python-version: '3.8' + python-version: ${{ env.MIN_PYTHON_VERSION }} - name: Install dependencies run: | @@ -54,7 +60,7 @@ jobs: strategy: fail-fast: true matrix: - python: ['3.9', '3.10', '3.11', '3.12', '3.13'] + python: ['3.10', '3.11', '3.12', '3.13'] steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b # v5.3.0 diff --git a/.github/workflows/update-bundle-report.yml b/.github/workflows/update-bundle-report.yml index 7046b517..7c03b158 100644 --- a/.github/workflows/update-bundle-report.yml +++ b/.github/workflows/update-bundle-report.yml @@ -6,6 +6,12 @@ on: - cron: '0 0 1 * *' workflow_dispatch: +permissions: + contents: read + +env: + MIN_PYTHON_VERSION: "3.9" + jobs: update: runs-on: ubuntu-latest @@ -15,7 +21,7 @@ jobs: - name: Setup python uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b # v5.3.0 with: - python-version: '3.8' + python-version: ${{ env.MIN_PYTHON_VERSION }} - name: Install dependencies run: | diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index cf05935e..82d526a4 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,10 +1,10 @@ repos: - repo: https://github.com/rhysd/actionlint - rev: v1.7.1 + rev: v1.7.6 hooks: - id: actionlint-docker - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.6.2 + rev: v0.8.6 hooks: - id: ruff files: ^(cloudsplaining/|setup.py) diff --git a/.python-version b/.python-version index cc1923a4..bd28b9c5 100644 --- a/.python-version +++ b/.python-version @@ -1 +1 @@ -3.8 +3.9 diff --git a/.readthedocs.yml b/.readthedocs.yml index 9ca3d459..ffbbf937 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -5,9 +5,9 @@ version: 2 build: - os: ubuntu-22.04 + os: ubuntu-24.04 tools: - python: "3.8" + python: "3.9" mkdocs: configuration: mkdocs.yml diff --git a/cloudsplaining/bin/version.py b/cloudsplaining/bin/version.py index 553d50a8..142a990e 100644 --- a/cloudsplaining/bin/version.py +++ b/cloudsplaining/bin/version.py @@ -1,2 +1,2 @@ # pylint: disable=missing-module-docstring -__version__ = "0.7.1" +__version__ = "0.8.0" diff --git a/cloudsplaining/output/policy_finding.py b/cloudsplaining/output/policy_finding.py index 3a7f733d..e0735b61 100644 --- a/cloudsplaining/output/policy_finding.py +++ b/cloudsplaining/output/policy_finding.py @@ -8,9 +8,8 @@ from __future__ import annotations import logging -from typing import Any +from typing import TYPE_CHECKING, Any -from cloudsplaining.scan.policy_document import PolicyDocument from cloudsplaining.shared.constants import ( ACTIONS_THAT_RETURN_CREDENTIALS, ISSUE_SEVERITY, @@ -23,6 +22,9 @@ is_name_excluded, ) +if TYPE_CHECKING: + from cloudsplaining.scan.policy_document import PolicyDocument + logger = logging.getLogger(__name__) diff --git a/cloudsplaining/scan/group_details.py b/cloudsplaining/scan/group_details.py index ef377faf..090bd86c 100644 --- a/cloudsplaining/scan/group_details.py +++ b/cloudsplaining/scan/group_details.py @@ -3,11 +3,9 @@ from __future__ import annotations import json -from typing import Any +from typing import TYPE_CHECKING, Any from cloudsplaining.scan.inline_policy import InlinePolicy -from cloudsplaining.scan.managed_policy_detail import ManagedPolicyDetails -from cloudsplaining.scan.statement_detail import StatementDetail from cloudsplaining.shared import utils from cloudsplaining.shared.exceptions import NotFoundException from cloudsplaining.shared.exclusions import DEFAULT_EXCLUSIONS, Exclusions @@ -18,6 +16,10 @@ is_aws_managed, ) +if TYPE_CHECKING: + from cloudsplaining.scan.managed_policy_detail import ManagedPolicyDetails + from cloudsplaining.scan.statement_detail import StatementDetail + class GroupDetailList: """Processes all entries under the GroupDetailList""" diff --git a/cloudsplaining/scan/resource_policy_document.py b/cloudsplaining/scan/resource_policy_document.py index 0f36ddfe..6e23729e 100644 --- a/cloudsplaining/scan/resource_policy_document.py +++ b/cloudsplaining/scan/resource_policy_document.py @@ -27,7 +27,7 @@ "saml:aud": "saml-endpoint", } RELEVANT_CONDITION_OPERATORS_PATTERN = re.compile( - "((ForAllValues|ForAnyValue):)?(ARN(Equals|Like)|String(Equals|Like)(IgnoreCase)?|IpAddress)(IfExists)?", + r"((ForAllValues|ForAnyValue):)?(ARN(Equals|Like)|String(Equals|Like)(IgnoreCase)?|IpAddress)(IfExists)?", re.IGNORECASE, ) diff --git a/cloudsplaining/scan/role_details.py b/cloudsplaining/scan/role_details.py index 8235627e..dc8179d5 100644 --- a/cloudsplaining/scan/role_details.py +++ b/cloudsplaining/scan/role_details.py @@ -4,12 +4,10 @@ import json import logging -from typing import Any +from typing import TYPE_CHECKING, Any from cloudsplaining.scan.assume_role_policy_document import AssumeRolePolicyDocument from cloudsplaining.scan.inline_policy import InlinePolicy -from cloudsplaining.scan.managed_policy_detail import ManagedPolicyDetails -from cloudsplaining.scan.statement_detail import StatementDetail from cloudsplaining.shared import utils from cloudsplaining.shared.exceptions import NotFoundException from cloudsplaining.shared.exclusions import ( @@ -24,6 +22,10 @@ is_aws_managed, ) +if TYPE_CHECKING: + from cloudsplaining.scan.managed_policy_detail import ManagedPolicyDetails + from cloudsplaining.scan.statement_detail import StatementDetail + logger = logging.getLogger(__name__) diff --git a/cloudsplaining/scan/user_details.py b/cloudsplaining/scan/user_details.py index fdd1aeee..ecd0ab05 100644 --- a/cloudsplaining/scan/user_details.py +++ b/cloudsplaining/scan/user_details.py @@ -3,12 +3,9 @@ from __future__ import annotations import json -from typing import Any +from typing import TYPE_CHECKING, Any -from cloudsplaining.scan.group_details import GroupDetail, GroupDetailList from cloudsplaining.scan.inline_policy import InlinePolicy -from cloudsplaining.scan.managed_policy_detail import ManagedPolicyDetails -from cloudsplaining.scan.statement_detail import StatementDetail from cloudsplaining.shared import utils from cloudsplaining.shared.exceptions import NotFoundException from cloudsplaining.shared.exclusions import DEFAULT_EXCLUSIONS, Exclusions @@ -19,6 +16,11 @@ is_aws_managed, ) +if TYPE_CHECKING: + from cloudsplaining.scan.group_details import GroupDetail, GroupDetailList + from cloudsplaining.scan.managed_policy_detail import ManagedPolicyDetails + from cloudsplaining.scan.statement_detail import StatementDetail + class UserDetailList: """Processes all entries under the UserDetailList""" diff --git a/pyproject.toml b/pyproject.toml index 5293913d..a902ed3f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -14,7 +14,7 @@ ignore_missing_imports = true [tool.ruff] line-length = 120 -target-version = "py38" +target-version = "py39" [tool.ruff.lint] preview = true @@ -38,12 +38,15 @@ select = [ "S", "SIM", "T10", + "TC", "UP", "W", "YTT", ] ignore = ["E501"] # ruff fromat takes care of it +fixable = ["I001"] + [tool.pytest.ini_options] testpaths = [ "test", diff --git a/requirements-dev.txt b/requirements-dev.txt index 7d8be63b..aaf4f094 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -1,9 +1,9 @@ # CI -pre-commit==3.5.0 # 3.6+ requires Python 3.9 +pre-commit==4.0.1 # Unit testing pytest==8.3.4 -coverage==7.6.1 +coverage==7.6.10 # type check -mypy==1.14.1 +mypy[faster-cache]==1.14.1 boto3-stubs-lite[iam,s3,sts]==1.35.70 types-PyYAML==6.0.12.20241230 diff --git a/requirements.txt b/requirements.txt index 17309509..3db83b4c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -12,6 +12,6 @@ pyyaml==6.0.2 # We render Markdown glossary files as HTML in the Cloudsplaining report markdown==3.7 # AWS IAM Logic -policy-sentry==0.13.2 +policy-sentry==0.14.0 # Schema validation schema==0.7.7 diff --git a/setup.py b/setup.py index 1b21629c..14e9cdaa 100644 --- a/setup.py +++ b/setup.py @@ -19,7 +19,7 @@ "click_option_group", "jinja2", "markdown", - "policy_sentry>=0.13.0,<0.14", + "policy_sentry>=0.14.0,<0.15", "pyyaml", "schema", ] @@ -57,7 +57,6 @@ def get_description() -> str: project_urls=PROJECT_URLS, classifiers=[ "Programming Language :: Python :: 3 :: Only", - "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11",