diff --git a/.github/workflows/api-security.yml b/.github/workflows/api-security.yml
index e8a8efc879..cf5403df99 100644
--- a/.github/workflows/api-security.yml
+++ b/.github/workflows/api-security.yml
@@ -1,14 +1,14 @@
-name: 'API: Security'
+name: "API: Security"
on:
push:
branches:
- - 'master'
- - 'v5.*'
+ - "master"
+ - "v5.*"
pull_request:
branches:
- - 'master'
- - 'v5.*'
+ - "master"
+ - "v5.*"
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
@@ -26,7 +26,7 @@ jobs:
strategy:
matrix:
python-version:
- - '3.12'
+ - "3.12"
defaults:
run:
working-directory: ./api
@@ -61,8 +61,9 @@ jobs:
- name: Safety
if: steps.check-changes.outputs.any_changed == 'true'
- run: poetry run safety check --ignore 79023,79027
+ run: poetry run safety check --ignore 79023,79027,84420
# TODO: 79023 & 79027 knack ReDoS until `azure-cli-core` (via `cartography`) allows `knack` >=0.13.0
+ # TODO: 84420 from `azure-core`, that we need fix alltogether with `azure-cli-core` and `knack`
- name: Vulture
if: steps.check-changes.outputs.any_changed == 'true'
diff --git a/.github/workflows/labeler.yml b/.github/workflows/labeler.yml
index 85ccd34cc2..1f44080229 100644
--- a/.github/workflows/labeler.yml
+++ b/.github/workflows/labeler.yml
@@ -51,18 +51,16 @@ jobs:
"amitsharm"
"andoniaf"
"cesararroba"
- "Chan9390"
"danibarranqueroo"
"HugoPBrito"
"jfagoagas"
- "josemazo"
+ "josema-xyz"
"lydiavilchez"
"mmuller88"
- "MrCloudSec"
+ # "MrCloudSec"
"pedrooot"
"prowler-bot"
"puchy22"
- "rakan-pro"
"RosaRivasProwler"
"StylusFrost"
"toniblyx"
diff --git a/.github/workflows/sdk-refresh-oci-regions.yml b/.github/workflows/sdk-refresh-oci-regions.yml
new file mode 100644
index 0000000000..35cbf37828
--- /dev/null
+++ b/.github/workflows/sdk-refresh-oci-regions.yml
@@ -0,0 +1,93 @@
+name: 'SDK: Refresh OCI Regions'
+
+on:
+ schedule:
+ - cron: '0 9 * * 1' # Every Monday at 09:00 UTC
+ workflow_dispatch:
+
+concurrency:
+ group: ${{ github.workflow }}
+ cancel-in-progress: false
+
+env:
+ PYTHON_VERSION: '3.12'
+
+jobs:
+ refresh-oci-regions:
+ if: github.repository == 'prowler-cloud/prowler'
+ runs-on: ubuntu-latest
+ timeout-minutes: 15
+ permissions:
+ pull-requests: write
+ contents: write
+
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
+ with:
+ ref: 'master'
+
+ - name: Set up Python ${{ env.PYTHON_VERSION }}
+ uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0
+ with:
+ python-version: ${{ env.PYTHON_VERSION }}
+ cache: 'pip'
+
+ - name: Install dependencies
+ run: pip install oci
+
+ - name: Update OCI regions
+ env:
+ OCI_CLI_USER: ${{ secrets.E2E_OCI_USER_ID }}
+ OCI_CLI_FINGERPRINT: ${{ secrets.E2E_OCI_FINGERPRINT }}
+ OCI_CLI_TENANCY: ${{ secrets.E2E_OCI_TENANCY_ID }}
+ OCI_CLI_KEY_CONTENT: ${{ secrets.E2E_OCI_KEY_CONTENT }}
+ OCI_CLI_REGION: ${{ secrets.E2E_OCI_REGION }}
+ run: python util/update_oci_regions.py
+
+ - name: Create pull request
+ id: create-pr
+ uses: peter-evans/create-pull-request@98357b18bf14b5342f975ff684046ec3b2a07725 # v8.0.0
+ with:
+ token: ${{ secrets.PROWLER_BOT_ACCESS_TOKEN }}
+ author: 'prowler-bot <179230569+prowler-bot@users.noreply.github.com>'
+ committer: 'github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>'
+ commit-message: 'feat(oraclecloud): update commercial regions'
+ branch: 'oci-regions-update-${{ github.run_number }}'
+ title: 'feat(oraclecloud): Update commercial regions'
+ labels: |
+ status/waiting-for-revision
+ no-changelog
+ body: |
+ ### Description
+
+ Automated update of OCI commercial regions from the official Oracle Cloud Infrastructure Identity service.
+
+ **Trigger:** ${{ github.event_name == 'schedule' && 'Scheduled (weekly)' || github.event_name == 'workflow_dispatch' && 'Manual' || 'Workflow update' }}
+ **Run:** [#${{ github.run_number }}](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})
+
+ ### Changes
+
+ This PR updates the `OCI_COMMERCIAL_REGIONS` dictionary in `prowler/providers/oraclecloud/config.py` with the latest regions fetched from the OCI Identity API (`list_regions()`).
+
+ - Government regions (`OCI_GOVERNMENT_REGIONS`) are preserved unchanged
+ - Region display names are mapped from Oracle's official documentation
+
+ ### Checklist
+
+ - [x] This is an automated update from OCI official sources
+ - [x] Government regions (us-langley-1, us-luke-1) preserved
+ - [x] No manual review of region data required
+
+ ### License
+
+ By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
+
+ - name: PR creation result
+ run: |
+ if [[ "${{ steps.create-pr.outputs.pull-request-number }}" ]]; then
+ echo "✓ Pull request #${{ steps.create-pr.outputs.pull-request-number }} created successfully"
+ echo "URL: ${{ steps.create-pr.outputs.pull-request-url }}"
+ else
+ echo "✓ No changes detected - OCI regions are up to date"
+ fi
diff --git a/.github/workflows/ui-e2e-tests-v2.yml b/.github/workflows/ui-e2e-tests-v2.yml
index caa712f3dd..9936737320 100644
--- a/.github/workflows/ui-e2e-tests-v2.yml
+++ b/.github/workflows/ui-e2e-tests-v2.yml
@@ -65,6 +65,10 @@ jobs:
E2E_OCI_KEY_CONTENT: ${{ secrets.E2E_OCI_KEY_CONTENT }}
E2E_OCI_REGION: ${{ secrets.E2E_OCI_REGION }}
E2E_NEW_USER_PASSWORD: ${{ secrets.E2E_NEW_USER_PASSWORD }}
+ E2E_ALIBABACLOUD_ACCOUNT_ID: ${{ secrets.E2E_ALIBABACLOUD_ACCOUNT_ID }}
+ E2E_ALIBABACLOUD_ACCESS_KEY_ID: ${{ secrets.E2E_ALIBABACLOUD_ACCESS_KEY_ID }}
+ E2E_ALIBABACLOUD_ACCESS_KEY_SECRET: ${{ secrets.E2E_ALIBABACLOUD_ACCESS_KEY_SECRET }}
+ E2E_ALIBABACLOUD_ROLE_ARN: ${{ secrets.E2E_ALIBABACLOUD_ROLE_ARN }}
# Pass E2E paths from impact analysis
E2E_TEST_PATHS: ${{ needs.impact-analysis.outputs.ui-e2e }}
RUN_ALL_TESTS: ${{ needs.impact-analysis.outputs.run-all }}
diff --git a/.github/workflows/ui-tests.yml b/.github/workflows/ui-tests.yml
index e7d1834f91..cc1a318277 100644
--- a/.github/workflows/ui-tests.yml
+++ b/.github/workflows/ui-tests.yml
@@ -44,6 +44,35 @@ jobs:
ui/README.md
ui/AGENTS.md
+ - name: Get changed source files for targeted tests
+ id: changed-source
+ if: steps.check-changes.outputs.any_changed == 'true'
+ uses: tj-actions/changed-files@e0021407031f5be11a464abee9a0776171c79891 # v47.0.1
+ with:
+ files: |
+ ui/**/*.ts
+ ui/**/*.tsx
+ files_ignore: |
+ ui/**/*.test.ts
+ ui/**/*.test.tsx
+ ui/**/*.spec.ts
+ ui/**/*.spec.tsx
+ ui/vitest.config.ts
+ ui/vitest.setup.ts
+
+ - name: Check for critical path changes (run all tests)
+ id: critical-changes
+ if: steps.check-changes.outputs.any_changed == 'true'
+ uses: tj-actions/changed-files@e0021407031f5be11a464abee9a0776171c79891 # v47.0.1
+ with:
+ files: |
+ ui/lib/**
+ ui/types/**
+ ui/config/**
+ ui/middleware.ts
+ ui/vitest.config.ts
+ ui/vitest.setup.ts
+
- name: Setup Node.js ${{ env.NODE_VERSION }}
if: steps.check-changes.outputs.any_changed == 'true'
uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0
@@ -83,6 +112,27 @@ jobs:
if: steps.check-changes.outputs.any_changed == 'true'
run: pnpm run healthcheck
+ - name: Run unit tests (all - critical paths changed)
+ if: steps.check-changes.outputs.any_changed == 'true' && steps.critical-changes.outputs.any_changed == 'true'
+ run: |
+ echo "Critical paths changed - running ALL unit tests"
+ pnpm run test:run
+
+ - name: Run unit tests (related to changes only)
+ if: steps.check-changes.outputs.any_changed == 'true' && steps.critical-changes.outputs.any_changed != 'true' && steps.changed-source.outputs.all_changed_files != ''
+ run: |
+ echo "Running tests related to changed files:"
+ echo "${{ steps.changed-source.outputs.all_changed_files }}"
+ # Convert space-separated to vitest related format (remove ui/ prefix for relative paths)
+ CHANGED_FILES=$(echo "${{ steps.changed-source.outputs.all_changed_files }}" | tr ' ' '\n' | sed 's|^ui/||' | tr '\n' ' ')
+ pnpm exec vitest related $CHANGED_FILES --run
+
+ - name: Run unit tests (test files only changed)
+ if: steps.check-changes.outputs.any_changed == 'true' && steps.critical-changes.outputs.any_changed != 'true' && steps.changed-source.outputs.all_changed_files == ''
+ run: |
+ echo "Only test files changed - running ALL unit tests"
+ pnpm run test:run
+
- name: Build application
if: steps.check-changes.outputs.any_changed == 'true'
run: pnpm run build
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 0a4164bc43..0aaf524047 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -85,7 +85,6 @@ repos:
args: ["--directory=./"]
pass_filenames: false
-
- repo: https://github.com/hadolint/hadolint
rev: v2.13.0-beta
hooks:
@@ -121,7 +120,8 @@ repos:
description: "Safety is a tool that checks your installed dependencies for known security vulnerabilities"
# TODO: Botocore needs urllib3 1.X so we need to ignore these vulnerabilities 77744,77745. Remove this once we upgrade to urllib3 2.X
# TODO: 79023 & 79027 knack ReDoS until `azure-cli-core` (via `cartography`) allows `knack` >=0.13.0
- entry: bash -c 'safety check --ignore 70612,66963,74429,76352,76353,77744,77745,79023,79027'
+ # TODO: 84420 from `azure-core`, that we need fix alltogether with `azure-cli-core` and `knack`
+ entry: bash -c 'safety check --ignore 70612,66963,74429,76352,76353,77744,77745,79023,79027,84420'
language: system
- id: vulture
diff --git a/AGENTS.md b/AGENTS.md
index 5d31782ef1..c0b5209a73 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -24,6 +24,8 @@ Use these skills for detailed patterns on-demand:
| `zod-4` | New API (z.email(), z.uuid()) | [SKILL.md](skills/zod-4/SKILL.md) |
| `zustand-5` | Persist, selectors, slices | [SKILL.md](skills/zustand-5/SKILL.md) |
| `ai-sdk-5` | UIMessage, streaming, LangChain | [SKILL.md](skills/ai-sdk-5/SKILL.md) |
+| `vitest` | Unit testing, React Testing Library | [SKILL.md](skills/vitest/SKILL.md) |
+| `tdd` | Test-Driven Development workflow | [SKILL.md](skills/tdd/SKILL.md) |
### Prowler-Specific Skills
| Skill | Description | URL |
@@ -56,8 +58,8 @@ When performing these actions, ALWAYS invoke the corresponding skill FIRST:
| Add changelog entry for a PR or feature | `prowler-changelog` |
| Adding DRF pagination or permissions | `django-drf` |
| Adding new providers | `prowler-provider` |
-| Adding services to existing providers | `prowler-provider` |
| Adding privilege escalation detection queries | `prowler-attack-paths-query` |
+| Adding services to existing providers | `prowler-provider` |
| After creating/modifying a skill | `skill-sync` |
| App Router / Server Actions | `nextjs-15` |
| Building AI chat features | `ai-sdk-5` |
@@ -76,30 +78,38 @@ When performing these actions, ALWAYS invoke the corresponding skill FIRST:
| Creating/updating compliance frameworks | `prowler-compliance` |
| Debug why a GitHub Actions job is failing | `prowler-ci` |
| Fill .github/pull_request_template.md (Context/Description/Steps to review/Checklist) | `prowler-pr` |
+| Fixing bug | `tdd` |
| General Prowler development questions | `prowler` |
| Implementing JSON:API endpoints | `django-drf` |
+| Implementing feature | `tdd` |
| Inspect PR CI checks and gates (.github/workflows/*) | `prowler-ci` |
| Inspect PR CI workflows (.github/workflows/*): conventional-commit, pr-check-changelog, pr-conflict-checker, labeler | `prowler-pr` |
| Mapping checks to compliance controls | `prowler-compliance` |
| Mocking AWS with moto in tests | `prowler-test-sdk` |
| Modifying API responses | `jsonapi` |
+| Modifying component | `tdd` |
+| Refactoring code | `tdd` |
| Regenerate AGENTS.md Auto-invoke tables (sync.sh) | `skill-sync` |
| Review PR requirements: template, title conventions, changelog gate | `prowler-pr` |
| Review changelog format and conventions | `prowler-changelog` |
| Reviewing JSON:API compliance | `jsonapi` |
| Reviewing compliance framework PRs | `prowler-compliance-review` |
| Testing RLS tenant isolation | `prowler-test-api` |
+| Testing hooks or utilities | `vitest` |
| Troubleshoot why a skill is missing from AGENTS.md auto-invoke | `skill-sync` |
| Understand CODEOWNERS/labeler-based automation | `prowler-ci` |
| Understand PR title conventional-commit validation | `prowler-ci` |
| Understand changelog gate and no-changelog label behavior | `prowler-ci` |
| Understand review ownership with CODEOWNERS | `prowler-pr` |
| Update CHANGELOG.md in any component | `prowler-changelog` |
+| Updating README.md provider statistics table | `prowler-readme-table` |
+| Updating checks, services, compliance, or categories count in README.md | `prowler-readme-table` |
| Updating existing Attack Paths queries | `prowler-attack-paths-query` |
| Updating existing checks and metadata | `prowler-sdk-check` |
| Using Zustand stores | `zustand-5` |
| Working on MCP server tools | `prowler-mcp` |
| Working on Prowler UI structure (actions/adapters/types/hooks) | `prowler-ui` |
+| Working on task | `tdd` |
| Working with Prowler UI test helpers/pages | `prowler-test-ui` |
| Working with Tailwind classes | `tailwind-4` |
| Writing Playwright E2E tests | `playwright` |
@@ -107,9 +117,12 @@ When performing these actions, ALWAYS invoke the corresponding skill FIRST:
| Writing Prowler SDK tests | `prowler-test-sdk` |
| Writing Prowler UI E2E tests | `prowler-test-ui` |
| Writing Python tests with pytest | `pytest` |
+| Writing React component tests | `vitest` |
| Writing React components | `react-19` |
| Writing TypeScript types/interfaces | `typescript` |
+| Writing Vitest tests | `vitest` |
| Writing documentation | `prowler-docs` |
+| Writing unit tests for UI | `vitest` |
---
diff --git a/README.md b/README.md
index d583a33a15..9e5be11c53 100644
--- a/README.md
+++ b/README.md
@@ -104,15 +104,15 @@ Every AWS provider scan will enqueue an Attack Paths ingestion job automatically
| Provider | Checks | Services | [Compliance Frameworks](https://docs.prowler.com/projects/prowler-open-source/en/latest/tutorials/compliance/) | [Categories](https://docs.prowler.com/projects/prowler-open-source/en/latest/tutorials/misc/#categories) | Support | Interface |
|---|---|---|---|---|---|---|
-| AWS | 585 | 84 | 40 | 17 | Official | UI, API, CLI |
-| Azure | 169 | 22 | 17 | 13 | Official | UI, API, CLI |
-| GCP | 100 | 17 | 14 | 7 | Official | UI, API, CLI |
-| Kubernetes | 84 | 7 | 7 | 9 | Official | UI, API, CLI |
-| GitHub | 20 | 2 | 1 | 2 | Official | UI, API, CLI |
-| M365 | 72 | 7 | 4 | 4 | Official | UI, API, CLI |
-| OCI | 52 | 14 | 1 | 12 | Official | UI, API, CLI |
-| Alibaba Cloud | 64 | 9 | 2 | 9 | Official | UI, API, CLI |
-| Cloudflare | 29 | 3 | 0 | 5 | Official | CLI |
+| AWS | 572 | 83 | 41 | 17 | Official | UI, API, CLI |
+| Azure | 165 | 20 | 18 | 13 | Official | UI, API, CLI |
+| GCP | 100 | 13 | 15 | 11 | Official | UI, API, CLI |
+| Kubernetes | 83 | 7 | 7 | 9 | Official | UI, API, CLI |
+| GitHub | 21 | 2 | 1 | 2 | Official | UI, API, CLI |
+| M365 | 75 | 7 | 4 | 4 | Official | UI, API, CLI |
+| OCI | 51 | 13 | 3 | 12 | Official | UI, API, CLI |
+| Alibaba Cloud | 61 | 9 | 3 | 9 | Official | UI, API, CLI |
+| Cloudflare | 29 | 2 | 0 | 5 | Official | CLI, API |
| IaC | [See `trivy` docs.](https://trivy.dev/latest/docs/coverage/iac/) | N/A | N/A | N/A | Official | UI, API, CLI |
| MongoDB Atlas | 10 | 3 | 0 | 3 | Official | UI, API, CLI |
| LLM | [See `promptfoo` docs.](https://www.promptfoo.dev/docs/red-team/plugins/) | N/A | N/A | N/A | Official | CLI |
diff --git a/api/AGENTS.md b/api/AGENTS.md
index e1e989d751..e1738b4a26 100644
--- a/api/AGENTS.md
+++ b/api/AGENTS.md
@@ -24,13 +24,18 @@ When performing these actions, ALWAYS invoke the corresponding skill FIRST:
| Creating ViewSets, serializers, or filters in api/ | `django-drf` |
| Creating a git commit | `prowler-commit` |
| Creating/modifying models, views, serializers | `prowler-api` |
+| Fixing bug | `tdd` |
| Implementing JSON:API endpoints | `django-drf` |
+| Implementing feature | `tdd` |
| Modifying API responses | `jsonapi` |
+| Modifying component | `tdd` |
+| Refactoring code | `tdd` |
| Review changelog format and conventions | `prowler-changelog` |
| Reviewing JSON:API compliance | `jsonapi` |
| Testing RLS tenant isolation | `prowler-test-api` |
| Update CHANGELOG.md in any component | `prowler-changelog` |
| Updating existing Attack Paths queries | `prowler-attack-paths-query` |
+| Working on task | `tdd` |
| Writing Prowler API tests | `prowler-test-api` |
| Writing Python tests with pytest | `pytest` |
diff --git a/api/CHANGELOG.md b/api/CHANGELOG.md
index 4b404586a1..2197a9a40b 100644
--- a/api/CHANGELOG.md
+++ b/api/CHANGELOG.md
@@ -2,6 +2,54 @@
All notable changes to the **Prowler API** are documented in this file.
+## [1.20.0] (Prowler UNRELEASED)
+
+### 🚀 Added
+
+- OpenStack provider support [(#10003)](https://github.com/prowler-cloud/prowler/pull/10003)
+- PDF report for the CSA CCM compliance framework [(#10088)](https://github.com/prowler-cloud/prowler/pull/10088)
+
+### 🔄 Changed
+
+- Attack Paths: Queries definition now has short description and attribution [(#9983)](https://github.com/prowler-cloud/prowler/pull/9983)
+- Attack Paths: Internet node is created while scan [(#9992)](https://github.com/prowler-cloud/prowler/pull/9992)
+- Attack Paths: Add full paths set from [pathfinding.cloud](https://pathfinding.cloud/) [(#10008)](https://github.com/prowler-cloud/prowler/pull/10008)
+- Support CSA CCM 4.0 for the AWS provider [(#10018)](https://github.com/prowler-cloud/prowler/pull/10018)
+- Support CSA CCM 4.0 for the GCP provider [(#10042)](https://github.com/prowler-cloud/prowler/pull/10042)
+- Support CSA CCM 4.0 for the Azure provider [(#10039)](https://github.com/prowler-cloud/prowler/pull/10039)
+- Support CSA CCM 4.0 for the Oracle Cloud provider [(#10057)](https://github.com/prowler-cloud/prowler/pull/10057)
+- Support CSA CCM 4.0 for the Alibaba Cloud provider [(#10061)](https://github.com/prowler-cloud/prowler/pull/10061)
+- Attack Paths: Mark attack Paths scan as failed when Celery task fails outside job error handling [(#10065)](https://github.com/prowler-cloud/prowler/pull/10065)
+- Attack Paths: Remove legacy per-scan `graph_database` and `is_graph_database_deleted` fields from AttackPathsScan model [(#10077)](https://github.com/prowler-cloud/prowler/pull/10077)
+- Attack Paths: Add `graph_data_ready` field to decouple query availability from scan state [(#10089)](https://github.com/prowler-cloud/prowler/pull/10089)
+- AI agent guidelines with TDD and testing skills references [(#9925)](https://github.com/prowler-cloud/prowler/pull/9925)
+
+### 🐞 Fixed
+
+- Attack Paths: Orphaned temporary Neo4j databases are now cleaned up on scan failure and provider deletion [(#10101)](https://github.com/prowler-cloud/prowler/pull/10101)
+
+### 🔐 Security
+
+- Bump `Pillow` to 12.1.1 (CVE-2021-25289) [(#10027)](https://github.com/prowler-cloud/prowler/pull/10027)
+
+---
+
+## [1.19.3] (Prowler UNRELEASED)
+
+### 🐞 Fixed
+
+- GCP provider UID validation regex to allow domain prefixes [(#10078)](https://github.com/prowler-cloud/prowler/pull/10078)
+
+---
+
+## [1.19.2] (Prowler v5.18.2)
+
+### 🐞 Fixed
+
+- SAML role mapping now prevents removing the last MANAGE_ACCOUNT user [(#10007)](https://github.com/prowler-cloud/prowler/pull/10007)
+
+---
+
## [1.19.0] (Prowler v5.18.0)
### 🚀 Added
diff --git a/api/poetry.lock b/api/poetry.lock
index 8ab49cf6bf..203147d55f 100644
--- a/api/poetry.lock
+++ b/api/poetry.lock
@@ -2508,43 +2508,49 @@ dev = ["bandit", "coverage", "flake8", "pydocstyle", "pylint", "pytest", "pytest
[[package]]
name = "cryptography"
-version = "44.0.1"
+version = "44.0.3"
description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers."
optional = false
python-versions = "!=3.9.0,!=3.9.1,>=3.7"
groups = ["main", "dev"]
files = [
- {file = "cryptography-44.0.1-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:bf688f615c29bfe9dfc44312ca470989279f0e94bb9f631f85e3459af8efc009"},
- {file = "cryptography-44.0.1-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd7c7e2d71d908dc0f8d2027e1604102140d84b155e658c20e8ad1304317691f"},
- {file = "cryptography-44.0.1-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:887143b9ff6bad2b7570da75a7fe8bbf5f65276365ac259a5d2d5147a73775f2"},
- {file = "cryptography-44.0.1-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:322eb03ecc62784536bc173f1483e76747aafeb69c8728df48537eb431cd1911"},
- {file = "cryptography-44.0.1-cp37-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:21377472ca4ada2906bc313168c9dc7b1d7ca417b63c1c3011d0c74b7de9ae69"},
- {file = "cryptography-44.0.1-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:df978682c1504fc93b3209de21aeabf2375cb1571d4e61907b3e7a2540e83026"},
- {file = "cryptography-44.0.1-cp37-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:eb3889330f2a4a148abead555399ec9a32b13b7c8ba969b72d8e500eb7ef84cd"},
- {file = "cryptography-44.0.1-cp37-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:8e6a85a93d0642bd774460a86513c5d9d80b5c002ca9693e63f6e540f1815ed0"},
- {file = "cryptography-44.0.1-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:6f76fdd6fd048576a04c5210d53aa04ca34d2ed63336d4abd306d0cbe298fddf"},
- {file = "cryptography-44.0.1-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:6c8acf6f3d1f47acb2248ec3ea261171a671f3d9428e34ad0357148d492c7864"},
- {file = "cryptography-44.0.1-cp37-abi3-win32.whl", hash = "sha256:24979e9f2040c953a94bf3c6782e67795a4c260734e5264dceea65c8f4bae64a"},
- {file = "cryptography-44.0.1-cp37-abi3-win_amd64.whl", hash = "sha256:fd0ee90072861e276b0ff08bd627abec29e32a53b2be44e41dbcdf87cbee2b00"},
- {file = "cryptography-44.0.1-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:a2d8a7045e1ab9b9f803f0d9531ead85f90c5f2859e653b61497228b18452008"},
- {file = "cryptography-44.0.1-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b8272f257cf1cbd3f2e120f14c68bff2b6bdfcc157fafdee84a1b795efd72862"},
- {file = "cryptography-44.0.1-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1e8d181e90a777b63f3f0caa836844a1182f1f265687fac2115fcf245f5fbec3"},
- {file = "cryptography-44.0.1-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:436df4f203482f41aad60ed1813811ac4ab102765ecae7a2bbb1dbb66dcff5a7"},
- {file = "cryptography-44.0.1-cp39-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:4f422e8c6a28cf8b7f883eb790695d6d45b0c385a2583073f3cec434cc705e1a"},
- {file = "cryptography-44.0.1-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:72198e2b5925155497a5a3e8c216c7fb3e64c16ccee11f0e7da272fa93b35c4c"},
- {file = "cryptography-44.0.1-cp39-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:2a46a89ad3e6176223b632056f321bc7de36b9f9b93b2cc1cccf935a3849dc62"},
- {file = "cryptography-44.0.1-cp39-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:53f23339864b617a3dfc2b0ac8d5c432625c80014c25caac9082314e9de56f41"},
- {file = "cryptography-44.0.1-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:888fcc3fce0c888785a4876ca55f9f43787f4c5c1cc1e2e0da71ad481ff82c5b"},
- {file = "cryptography-44.0.1-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:00918d859aa4e57db8299607086f793fa7813ae2ff5a4637e318a25ef82730f7"},
- {file = "cryptography-44.0.1-cp39-abi3-win32.whl", hash = "sha256:9b336599e2cb77b1008cb2ac264b290803ec5e8e89d618a5e978ff5eb6f715d9"},
- {file = "cryptography-44.0.1-cp39-abi3-win_amd64.whl", hash = "sha256:e403f7f766ded778ecdb790da786b418a9f2394f36e8cc8b796cc056ab05f44f"},
- {file = "cryptography-44.0.1-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:1f9a92144fa0c877117e9748c74501bea842f93d21ee00b0cf922846d9d0b183"},
- {file = "cryptography-44.0.1-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:610a83540765a8d8ce0f351ce42e26e53e1f774a6efb71eb1b41eb01d01c3d12"},
- {file = "cryptography-44.0.1-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:5fed5cd6102bb4eb843e3315d2bf25fede494509bddadb81e03a859c1bc17b83"},
- {file = "cryptography-44.0.1-pp310-pypy310_pp73-manylinux_2_34_aarch64.whl", hash = "sha256:f4daefc971c2d1f82f03097dc6f216744a6cd2ac0f04c68fb935ea2ba2a0d420"},
- {file = "cryptography-44.0.1-pp310-pypy310_pp73-manylinux_2_34_x86_64.whl", hash = "sha256:94f99f2b943b354a5b6307d7e8d19f5c423a794462bde2bf310c770ba052b1c4"},
- {file = "cryptography-44.0.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:d9c5b9f698a83c8bd71e0f4d3f9f839ef244798e5ffe96febfa9714717db7af7"},
- {file = "cryptography-44.0.1.tar.gz", hash = "sha256:f51f5705ab27898afda1aaa430f34ad90dc117421057782022edf0600bec5f14"},
+ {file = "cryptography-44.0.3-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:962bc30480a08d133e631e8dfd4783ab71cc9e33d5d7c1e192f0b7c06397bb88"},
+ {file = "cryptography-44.0.3-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4ffc61e8f3bf5b60346d89cd3d37231019c17a081208dfbbd6e1605ba03fa137"},
+ {file = "cryptography-44.0.3-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:58968d331425a6f9eedcee087f77fd3c927c88f55368f43ff7e0a19891f2642c"},
+ {file = "cryptography-44.0.3-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:e28d62e59a4dbd1d22e747f57d4f00c459af22181f0b2f787ea83f5a876d7c76"},
+ {file = "cryptography-44.0.3-cp37-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:af653022a0c25ef2e3ffb2c673a50e5a0d02fecc41608f4954176f1933b12359"},
+ {file = "cryptography-44.0.3-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:157f1f3b8d941c2bd8f3ffee0af9b049c9665c39d3da9db2dc338feca5e98a43"},
+ {file = "cryptography-44.0.3-cp37-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:c6cd67722619e4d55fdb42ead64ed8843d64638e9c07f4011163e46bc512cf01"},
+ {file = "cryptography-44.0.3-cp37-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:b424563394c369a804ecbee9b06dfb34997f19d00b3518e39f83a5642618397d"},
+ {file = "cryptography-44.0.3-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:c91fc8e8fd78af553f98bc7f2a1d8db977334e4eea302a4bfd75b9461c2d8904"},
+ {file = "cryptography-44.0.3-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:25cd194c39fa5a0aa4169125ee27d1172097857b27109a45fadc59653ec06f44"},
+ {file = "cryptography-44.0.3-cp37-abi3-win32.whl", hash = "sha256:3be3f649d91cb182c3a6bd336de8b61a0a71965bd13d1a04a0e15b39c3d5809d"},
+ {file = "cryptography-44.0.3-cp37-abi3-win_amd64.whl", hash = "sha256:3883076d5c4cc56dbef0b898a74eb6992fdac29a7b9013870b34efe4ddb39a0d"},
+ {file = "cryptography-44.0.3-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:5639c2b16764c6f76eedf722dbad9a0914960d3489c0cc38694ddf9464f1bb2f"},
+ {file = "cryptography-44.0.3-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f3ffef566ac88f75967d7abd852ed5f182da252d23fac11b4766da3957766759"},
+ {file = "cryptography-44.0.3-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:192ed30fac1728f7587c6f4613c29c584abdc565d7417c13904708db10206645"},
+ {file = "cryptography-44.0.3-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:7d5fe7195c27c32a64955740b949070f21cba664604291c298518d2e255931d2"},
+ {file = "cryptography-44.0.3-cp39-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3f07943aa4d7dad689e3bb1638ddc4944cc5e0921e3c227486daae0e31a05e54"},
+ {file = "cryptography-44.0.3-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:cb90f60e03d563ca2445099edf605c16ed1d5b15182d21831f58460c48bffb93"},
+ {file = "cryptography-44.0.3-cp39-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:ab0b005721cc0039e885ac3503825661bd9810b15d4f374e473f8c89b7d5460c"},
+ {file = "cryptography-44.0.3-cp39-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:3bb0847e6363c037df8f6ede57d88eaf3410ca2267fb12275370a76f85786a6f"},
+ {file = "cryptography-44.0.3-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:b0cc66c74c797e1db750aaa842ad5b8b78e14805a9b5d1348dc603612d3e3ff5"},
+ {file = "cryptography-44.0.3-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:6866df152b581f9429020320e5eb9794c8780e90f7ccb021940d7f50ee00ae0b"},
+ {file = "cryptography-44.0.3-cp39-abi3-win32.whl", hash = "sha256:c138abae3a12a94c75c10499f1cbae81294a6f983b3af066390adee73f433028"},
+ {file = "cryptography-44.0.3-cp39-abi3-win_amd64.whl", hash = "sha256:5d186f32e52e66994dce4f766884bcb9c68b8da62d61d9d215bfe5fb56d21334"},
+ {file = "cryptography-44.0.3-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:cad399780053fb383dc067475135e41c9fe7d901a97dd5d9c5dfb5611afc0d7d"},
+ {file = "cryptography-44.0.3-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:21a83f6f35b9cc656d71b5de8d519f566df01e660ac2578805ab245ffd8523f8"},
+ {file = "cryptography-44.0.3-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:fc3c9babc1e1faefd62704bb46a69f359a9819eb0292e40df3fb6e3574715cd4"},
+ {file = "cryptography-44.0.3-pp310-pypy310_pp73-manylinux_2_34_aarch64.whl", hash = "sha256:e909df4053064a97f1e6565153ff8bb389af12c5c8d29c343308760890560aff"},
+ {file = "cryptography-44.0.3-pp310-pypy310_pp73-manylinux_2_34_x86_64.whl", hash = "sha256:dad80b45c22e05b259e33ddd458e9e2ba099c86ccf4e88db7bbab4b747b18d06"},
+ {file = "cryptography-44.0.3-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:479d92908277bed6e1a1c69b277734a7771c2b78633c224445b5c60a9f4bc1d9"},
+ {file = "cryptography-44.0.3-pp311-pypy311_pp73-macosx_10_9_x86_64.whl", hash = "sha256:896530bc9107b226f265effa7ef3f21270f18a2026bc09fed1ebd7b66ddf6375"},
+ {file = "cryptography-44.0.3-pp311-pypy311_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:9b4d4a5dbee05a2c390bf212e78b99434efec37b17a4bff42f50285c5c8c9647"},
+ {file = "cryptography-44.0.3-pp311-pypy311_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:02f55fb4f8b79c1221b0961488eaae21015b69b210e18c386b69de182ebb1259"},
+ {file = "cryptography-44.0.3-pp311-pypy311_pp73-manylinux_2_34_aarch64.whl", hash = "sha256:dd3db61b8fe5be220eee484a17233287d0be6932d056cf5738225b9c05ef4fff"},
+ {file = "cryptography-44.0.3-pp311-pypy311_pp73-manylinux_2_34_x86_64.whl", hash = "sha256:978631ec51a6bbc0b7e58f23b68a8ce9e5f09721940933e9c217068388789fe5"},
+ {file = "cryptography-44.0.3-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:5d20cc348cca3a8aa7312f42ab953a56e15323800ca3ab0706b8cd452a3a056c"},
+ {file = "cryptography-44.0.3.tar.gz", hash = "sha256:fe19d8bc5536a91a24a8133328880a41831b6c5df54599a8417b62fe015d3053"},
]
[package.dependencies]
@@ -2557,7 +2563,7 @@ nox = ["nox (>=2024.4.15)", "nox[uv] (>=2024.3.2) ; python_version >= \"3.8\""]
pep8test = ["check-sdist ; python_version >= \"3.8\"", "click (>=8.0.1)", "mypy (>=1.4)", "ruff (>=0.3.6)"]
sdist = ["build (>=1.0.0)"]
ssh = ["bcrypt (>=3.1.5)"]
-test = ["certifi (>=2024)", "cryptography-vectors (==44.0.1)", "pretend (>=0.7)", "pytest (>=7.4.0)", "pytest-benchmark (>=4.0)", "pytest-cov (>=2.10.1)", "pytest-xdist (>=3.5.0)"]
+test = ["certifi (>=2024)", "cryptography-vectors (==44.0.3)", "pretend (>=0.7)", "pytest (>=7.4.0)", "pytest-benchmark (>=4.0)", "pytest-cov (>=2.10.1)", "pytest-xdist (>=3.5.0)"]
test-randomorder = ["pytest-randomly"]
[[package]]
@@ -5830,46 +5836,6 @@ files = [
{file = "nest_asyncio-1.6.0.tar.gz", hash = "sha256:6f172d5449aca15afd6c646851f4e31e02c598d553a667e38cafa997cfec55fe"},
]
-[[package]]
-name = "netifaces"
-version = "0.11.0"
-description = "Portable network interface information."
-optional = false
-python-versions = "*"
-groups = ["main"]
-files = [
- {file = "netifaces-0.11.0-cp27-cp27m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:eb4813b77d5df99903af4757ce980a98c4d702bbcb81f32a0b305a1537bdf0b1"},
- {file = "netifaces-0.11.0-cp27-cp27m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:5f9ca13babe4d845e400921973f6165a4c2f9f3379c7abfc7478160e25d196a4"},
- {file = "netifaces-0.11.0-cp27-cp27m-win32.whl", hash = "sha256:7dbb71ea26d304e78ccccf6faccef71bb27ea35e259fb883cfd7fd7b4f17ecb1"},
- {file = "netifaces-0.11.0-cp27-cp27m-win_amd64.whl", hash = "sha256:0f6133ac02521270d9f7c490f0c8c60638ff4aec8338efeff10a1b51506abe85"},
- {file = "netifaces-0.11.0-cp27-cp27mu-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:08e3f102a59f9eaef70948340aeb6c89bd09734e0dca0f3b82720305729f63ea"},
- {file = "netifaces-0.11.0-cp27-cp27mu-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:c03fb2d4ef4e393f2e6ffc6376410a22a3544f164b336b3a355226653e5efd89"},
- {file = "netifaces-0.11.0-cp34-cp34m-win32.whl", hash = "sha256:73ff21559675150d31deea8f1f8d7e9a9a7e4688732a94d71327082f517fc6b4"},
- {file = "netifaces-0.11.0-cp35-cp35m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:815eafdf8b8f2e61370afc6add6194bd5a7252ae44c667e96c4c1ecf418811e4"},
- {file = "netifaces-0.11.0-cp35-cp35m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:50721858c935a76b83dd0dd1ab472cad0a3ef540a1408057624604002fcfb45b"},
- {file = "netifaces-0.11.0-cp35-cp35m-win32.whl", hash = "sha256:c9a3a47cd3aaeb71e93e681d9816c56406ed755b9442e981b07e3618fb71d2ac"},
- {file = "netifaces-0.11.0-cp36-cp36m-macosx_10_15_x86_64.whl", hash = "sha256:aab1dbfdc55086c789f0eb37affccf47b895b98d490738b81f3b2360100426be"},
- {file = "netifaces-0.11.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c37a1ca83825bc6f54dddf5277e9c65dec2f1b4d0ba44b8fd42bc30c91aa6ea1"},
- {file = "netifaces-0.11.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:28f4bf3a1361ab3ed93c5ef360c8b7d4a4ae060176a3529e72e5e4ffc4afd8b0"},
- {file = "netifaces-0.11.0-cp36-cp36m-win32.whl", hash = "sha256:2650beee182fed66617e18474b943e72e52f10a24dc8cac1db36c41ee9c041b7"},
- {file = "netifaces-0.11.0-cp36-cp36m-win_amd64.whl", hash = "sha256:cb925e1ca024d6f9b4f9b01d83215fd00fe69d095d0255ff3f64bffda74025c8"},
- {file = "netifaces-0.11.0-cp37-cp37m-macosx_10_15_x86_64.whl", hash = "sha256:84e4d2e6973eccc52778735befc01638498781ce0e39aa2044ccfd2385c03246"},
- {file = "netifaces-0.11.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:18917fbbdcb2d4f897153c5ddbb56b31fa6dd7c3fa9608b7e3c3a663df8206b5"},
- {file = "netifaces-0.11.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:48324183af7f1bc44f5f197f3dad54a809ad1ef0c78baee2c88f16a5de02c4c9"},
- {file = "netifaces-0.11.0-cp37-cp37m-win32.whl", hash = "sha256:8f7da24eab0d4184715d96208b38d373fd15c37b0dafb74756c638bd619ba150"},
- {file = "netifaces-0.11.0-cp37-cp37m-win_amd64.whl", hash = "sha256:2479bb4bb50968089a7c045f24d120f37026d7e802ec134c4490eae994c729b5"},
- {file = "netifaces-0.11.0-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:3ecb3f37c31d5d51d2a4d935cfa81c9bc956687c6f5237021b36d6fdc2815b2c"},
- {file = "netifaces-0.11.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:96c0fe9696398253f93482c84814f0e7290eee0bfec11563bd07d80d701280c3"},
- {file = "netifaces-0.11.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:c92ff9ac7c2282009fe0dcb67ee3cd17978cffbe0c8f4b471c00fe4325c9b4d4"},
- {file = "netifaces-0.11.0-cp38-cp38-win32.whl", hash = "sha256:d07b01c51b0b6ceb0f09fc48ec58debd99d2c8430b09e56651addeaf5de48048"},
- {file = "netifaces-0.11.0-cp38-cp38-win_amd64.whl", hash = "sha256:469fc61034f3daf095e02f9f1bbac07927b826c76b745207287bc594884cfd05"},
- {file = "netifaces-0.11.0-cp39-cp39-macosx_10_15_x86_64.whl", hash = "sha256:5be83986100ed1fdfa78f11ccff9e4757297735ac17391b95e17e74335c2047d"},
- {file = "netifaces-0.11.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:54ff6624eb95b8a07e79aa8817288659af174e954cca24cdb0daeeddfc03c4ff"},
- {file = "netifaces-0.11.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:841aa21110a20dc1621e3dd9f922c64ca64dd1eb213c47267a2c324d823f6c8f"},
- {file = "netifaces-0.11.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:e76c7f351e0444721e85f975ae92718e21c1f361bda946d60a214061de1f00a1"},
- {file = "netifaces-0.11.0.tar.gz", hash = "sha256:043a79146eb2907edf439899f262b3dfe41717d34124298ed281139a8b93ca32"},
-]
-
[[package]]
name = "nltk"
version = "3.9.2"
@@ -6037,14 +6003,14 @@ voice-helpers = ["numpy (>=2.0.2)", "sounddevice (>=0.5.1)"]
[[package]]
name = "openstacksdk"
-version = "4.0.1"
+version = "4.2.0"
description = "An SDK for building applications to work with OpenStack"
optional = false
-python-versions = ">=3.8"
+python-versions = ">=3.9"
groups = ["main"]
files = [
- {file = "openstacksdk-4.0.1-py3-none-any.whl", hash = "sha256:d63187a006fff7c1de1486c9e2e1073a787af402620c3c0ed0cf5291225998ac"},
- {file = "openstacksdk-4.0.1.tar.gz", hash = "sha256:19faa1d5e6a78a2c1dc06a171e65e776ba82e9df23e1d08586225dc5ade9fc63"},
+ {file = "openstacksdk-4.2.0-py3-none-any.whl", hash = "sha256:238be0fa5d9899872b00787ab38e84f92fd6dc87525fde0965dadcdc12196dc6"},
+ {file = "openstacksdk-4.2.0.tar.gz", hash = "sha256:5cb9450dcce8054a2caf89d8be9e55057ddfa219a954e781032241eb29280445"},
]
[package.dependencies]
@@ -6055,10 +6021,10 @@ iso8601 = ">=0.1.11"
jmespath = ">=0.9.0"
jsonpatch = ">=1.16,<1.20 || >1.20"
keystoneauth1 = ">=3.18.0"
-netifaces = ">=0.10.4"
os-service-types = ">=1.7.0"
pbr = ">=2.0.0,<2.1.0 || >2.1.0"
platformdirs = ">=3"
+psutil = ">=3.2.2"
PyYAML = ">=3.13"
requestsexceptions = ">=1.2.0"
@@ -6258,103 +6224,103 @@ urllib3 = "*"
[[package]]
name = "pillow"
-version = "12.1.0"
+version = "12.1.1"
description = "Python Imaging Library (fork)"
optional = false
python-versions = ">=3.10"
groups = ["main"]
files = [
- {file = "pillow-12.1.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:fb125d860738a09d363a88daa0f59c4533529a90e564785e20fe875b200b6dbd"},
- {file = "pillow-12.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:cad302dc10fac357d3467a74a9561c90609768a6f73a1923b0fd851b6486f8b0"},
- {file = "pillow-12.1.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:a40905599d8079e09f25027423aed94f2823adaf2868940de991e53a449e14a8"},
- {file = "pillow-12.1.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:92a7fe4225365c5e3a8e598982269c6d6698d3e783b3b1ae979e7819f9cd55c1"},
- {file = "pillow-12.1.0-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f10c98f49227ed8383d28174ee95155a675c4ed7f85e2e573b04414f7e371bda"},
- {file = "pillow-12.1.0-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8637e29d13f478bc4f153d8daa9ffb16455f0a6cb287da1b432fdad2bfbd66c7"},
- {file = "pillow-12.1.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:21e686a21078b0f9cb8c8a961d99e6a4ddb88e0fc5ea6e130172ddddc2e5221a"},
- {file = "pillow-12.1.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:2415373395a831f53933c23ce051021e79c8cd7979822d8cc478547a3f4da8ef"},
- {file = "pillow-12.1.0-cp310-cp310-win32.whl", hash = "sha256:e75d3dba8fc1ddfec0cd752108f93b83b4f8d6ab40e524a95d35f016b9683b09"},
- {file = "pillow-12.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:64efdf00c09e31efd754448a383ea241f55a994fd079866b92d2bbff598aad91"},
- {file = "pillow-12.1.0-cp310-cp310-win_arm64.whl", hash = "sha256:f188028b5af6b8fb2e9a76ac0f841a575bd1bd396e46ef0840d9b88a48fdbcea"},
- {file = "pillow-12.1.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:a83e0850cb8f5ac975291ebfc4170ba481f41a28065277f7f735c202cd8e0af3"},
- {file = "pillow-12.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b6e53e82ec2db0717eabb276aa56cf4e500c9a7cec2c2e189b55c24f65a3e8c0"},
- {file = "pillow-12.1.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:40a8e3b9e8773876d6e30daed22f016509e3987bab61b3b7fe309d7019a87451"},
- {file = "pillow-12.1.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:800429ac32c9b72909c671aaf17ecd13110f823ddb7db4dfef412a5587c2c24e"},
- {file = "pillow-12.1.0-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0b022eaaf709541b391ee069f0022ee5b36c709df71986e3f7be312e46f42c84"},
- {file = "pillow-12.1.0-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1f345e7bc9d7f368887c712aa5054558bad44d2a301ddf9248599f4161abc7c0"},
- {file = "pillow-12.1.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d70347c8a5b7ccd803ec0c85c8709f036e6348f1e6a5bf048ecd9c64d3550b8b"},
- {file = "pillow-12.1.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:1fcc52d86ce7a34fd17cb04e87cfdb164648a3662a6f20565910a99653d66c18"},
- {file = "pillow-12.1.0-cp311-cp311-win32.whl", hash = "sha256:3ffaa2f0659e2f740473bcf03c702c39a8d4b2b7ffc629052028764324842c64"},
- {file = "pillow-12.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:806f3987ffe10e867bab0ddad45df1148a2b98221798457fa097ad85d6e8bc75"},
- {file = "pillow-12.1.0-cp311-cp311-win_arm64.whl", hash = "sha256:9f5fefaca968e700ad1a4a9de98bf0869a94e397fe3524c4c9450c1445252304"},
- {file = "pillow-12.1.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:a332ac4ccb84b6dde65dbace8431f3af08874bf9770719d32a635c4ef411b18b"},
- {file = "pillow-12.1.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:907bfa8a9cb790748a9aa4513e37c88c59660da3bcfffbd24a7d9e6abf224551"},
- {file = "pillow-12.1.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:efdc140e7b63b8f739d09a99033aa430accce485ff78e6d311973a67b6bf3208"},
- {file = "pillow-12.1.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:bef9768cab184e7ae6e559c032e95ba8d07b3023c289f79a2bd36e8bf85605a5"},
- {file = "pillow-12.1.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:742aea052cf5ab5034a53c3846165bc3ce88d7c38e954120db0ab867ca242661"},
- {file = "pillow-12.1.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a6dfc2af5b082b635af6e08e0d1f9f1c4e04d17d4e2ca0ef96131e85eda6eb17"},
- {file = "pillow-12.1.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:609e89d9f90b581c8d16358c9087df76024cf058fa693dd3e1e1620823f39670"},
- {file = "pillow-12.1.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:43b4899cfd091a9693a1278c4982f3e50f7fb7cff5153b05174b4afc9593b616"},
- {file = "pillow-12.1.0-cp312-cp312-win32.whl", hash = "sha256:aa0c9cc0b82b14766a99fbe6084409972266e82f459821cd26997a488a7261a7"},
- {file = "pillow-12.1.0-cp312-cp312-win_amd64.whl", hash = "sha256:d70534cea9e7966169ad29a903b99fc507e932069a881d0965a1a84bb57f6c6d"},
- {file = "pillow-12.1.0-cp312-cp312-win_arm64.whl", hash = "sha256:65b80c1ee7e14a87d6a068dd3b0aea268ffcabfe0498d38661b00c5b4b22e74c"},
- {file = "pillow-12.1.0-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:7b5dd7cbae20285cdb597b10eb5a2c13aa9de6cde9bb64a3c1317427b1db1ae1"},
- {file = "pillow-12.1.0-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:29a4cef9cb672363926f0470afc516dbf7305a14d8c54f7abbb5c199cd8f8179"},
- {file = "pillow-12.1.0-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:681088909d7e8fa9e31b9799aaa59ba5234c58e5e4f1951b4c4d1082a2e980e0"},
- {file = "pillow-12.1.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:983976c2ab753166dc66d36af6e8ec15bb511e4a25856e2227e5f7e00a160587"},
- {file = "pillow-12.1.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:db44d5c160a90df2d24a24760bbd37607d53da0b34fb546c4c232af7192298ac"},
- {file = "pillow-12.1.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:6b7a9d1db5dad90e2991645874f708e87d9a3c370c243c2d7684d28f7e133e6b"},
- {file = "pillow-12.1.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:6258f3260986990ba2fa8a874f8b6e808cf5abb51a94015ca3dc3c68aa4f30ea"},
- {file = "pillow-12.1.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e115c15e3bc727b1ca3e641a909f77f8ca72a64fff150f666fcc85e57701c26c"},
- {file = "pillow-12.1.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6741e6f3074a35e47c77b23a4e4f2d90db3ed905cb1c5e6e0d49bff2045632bc"},
- {file = "pillow-12.1.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:935b9d1aed48fcfb3f838caac506f38e29621b44ccc4f8a64d575cb1b2a88644"},
- {file = "pillow-12.1.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:5fee4c04aad8932da9f8f710af2c1a15a83582cfb884152a9caa79d4efcdbf9c"},
- {file = "pillow-12.1.0-cp313-cp313-win32.whl", hash = "sha256:a786bf667724d84aa29b5db1c61b7bfdde380202aaca12c3461afd6b71743171"},
- {file = "pillow-12.1.0-cp313-cp313-win_amd64.whl", hash = "sha256:461f9dfdafa394c59cd6d818bdfdbab4028b83b02caadaff0ffd433faf4c9a7a"},
- {file = "pillow-12.1.0-cp313-cp313-win_arm64.whl", hash = "sha256:9212d6b86917a2300669511ed094a9406888362e085f2431a7da985a6b124f45"},
- {file = "pillow-12.1.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:00162e9ca6d22b7c3ee8e61faa3c3253cd19b6a37f126cad04f2f88b306f557d"},
- {file = "pillow-12.1.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:7d6daa89a00b58c37cb1747ec9fb7ac3bc5ffd5949f5888657dfddde6d1312e0"},
- {file = "pillow-12.1.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:e2479c7f02f9d505682dc47df8c0ea1fc5e264c4d1629a5d63fe3e2334b89554"},
- {file = "pillow-12.1.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f188d580bd870cda1e15183790d1cc2fa78f666e76077d103edf048eed9c356e"},
- {file = "pillow-12.1.0-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0fde7ec5538ab5095cc02df38ee99b0443ff0e1c847a045554cf5f9af1f4aa82"},
- {file = "pillow-12.1.0-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0ed07dca4a8464bada6139ab38f5382f83e5f111698caf3191cb8dbf27d908b4"},
- {file = "pillow-12.1.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:f45bd71d1fa5e5749587613037b172e0b3b23159d1c00ef2fc920da6f470e6f0"},
- {file = "pillow-12.1.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:277518bf4fe74aa91489e1b20577473b19ee70fb97c374aa50830b279f25841b"},
- {file = "pillow-12.1.0-cp313-cp313t-win32.whl", hash = "sha256:7315f9137087c4e0ee73a761b163fc9aa3b19f5f606a7fc08d83fd3e4379af65"},
- {file = "pillow-12.1.0-cp313-cp313t-win_amd64.whl", hash = "sha256:0ddedfaa8b5f0b4ffbc2fa87b556dc59f6bb4ecb14a53b33f9189713ae8053c0"},
- {file = "pillow-12.1.0-cp313-cp313t-win_arm64.whl", hash = "sha256:80941e6d573197a0c28f394753de529bb436b1ca990ed6e765cf42426abc39f8"},
- {file = "pillow-12.1.0-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:5cb7bc1966d031aec37ddb9dcf15c2da5b2e9f7cc3ca7c54473a20a927e1eb91"},
- {file = "pillow-12.1.0-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:97e9993d5ed946aba26baf9c1e8cf18adbab584b99f452ee72f7ee8acb882796"},
- {file = "pillow-12.1.0-cp314-cp314-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:414b9a78e14ffeb98128863314e62c3f24b8a86081066625700b7985b3f529bd"},
- {file = "pillow-12.1.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:e6bdb408f7c9dd2a5ff2b14a3b0bb6d4deb29fb9961e6eb3ae2031ae9a5cec13"},
- {file = "pillow-12.1.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:3413c2ae377550f5487991d444428f1a8ae92784aac79caa8b1e3b89b175f77e"},
- {file = "pillow-12.1.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:e5dcbe95016e88437ecf33544ba5db21ef1b8dd6e1b434a2cb2a3d605299e643"},
- {file = "pillow-12.1.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d0a7735df32ccbcc98b98a1ac785cc4b19b580be1bdf0aeb5c03223220ea09d5"},
- {file = "pillow-12.1.0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0c27407a2d1b96774cbc4a7594129cc027339fd800cd081e44497722ea1179de"},
- {file = "pillow-12.1.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:15c794d74303828eaa957ff8070846d0efe8c630901a1c753fdc63850e19ecd9"},
- {file = "pillow-12.1.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:c990547452ee2800d8506c4150280757f88532f3de2a58e3022e9b179107862a"},
- {file = "pillow-12.1.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:b63e13dd27da389ed9475b3d28510f0f954bca0041e8e551b2a4eb1eab56a39a"},
- {file = "pillow-12.1.0-cp314-cp314-win32.whl", hash = "sha256:1a949604f73eb07a8adab38c4fe50791f9919344398bdc8ac6b307f755fc7030"},
- {file = "pillow-12.1.0-cp314-cp314-win_amd64.whl", hash = "sha256:4f9f6a650743f0ddee5593ac9e954ba1bdbc5e150bc066586d4f26127853ab94"},
- {file = "pillow-12.1.0-cp314-cp314-win_arm64.whl", hash = "sha256:808b99604f7873c800c4840f55ff389936ef1948e4e87645eaf3fccbc8477ac4"},
- {file = "pillow-12.1.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:bc11908616c8a283cf7d664f77411a5ed2a02009b0097ff8abbba5e79128ccf2"},
- {file = "pillow-12.1.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:896866d2d436563fa2a43a9d72f417874f16b5545955c54a64941e87c1376c61"},
- {file = "pillow-12.1.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:8e178e3e99d3c0ea8fc64b88447f7cac8ccf058af422a6cedc690d0eadd98c51"},
- {file = "pillow-12.1.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:079af2fb0c599c2ec144ba2c02766d1b55498e373b3ac64687e43849fbbef5bc"},
- {file = "pillow-12.1.0-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bdec5e43377761c5dbca620efb69a77f6855c5a379e32ac5b158f54c84212b14"},
- {file = "pillow-12.1.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:565c986f4b45c020f5421a4cea13ef294dde9509a8577f29b2fc5edc7587fff8"},
- {file = "pillow-12.1.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:43aca0a55ce1eefc0aefa6253661cb54571857b1a7b2964bd8a1e3ef4b729924"},
- {file = "pillow-12.1.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:0deedf2ea233722476b3a81e8cdfbad786f7adbed5d848469fa59fe52396e4ef"},
- {file = "pillow-12.1.0-cp314-cp314t-win32.whl", hash = "sha256:b17fbdbe01c196e7e159aacb889e091f28e61020a8abeac07b68079b6e626988"},
- {file = "pillow-12.1.0-cp314-cp314t-win_amd64.whl", hash = "sha256:27b9baecb428899db6c0de572d6d305cfaf38ca1596b5c0542a5182e3e74e8c6"},
- {file = "pillow-12.1.0-cp314-cp314t-win_arm64.whl", hash = "sha256:f61333d817698bdcdd0f9d7793e365ac3d2a21c1f1eb02b32ad6aefb8d8ea831"},
- {file = "pillow-12.1.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:ca94b6aac0d7af2a10ba08c0f888b3d5114439b6b3ef39968378723622fed377"},
- {file = "pillow-12.1.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:351889afef0f485b84078ea40fe33727a0492b9af3904661b0abbafee0355b72"},
- {file = "pillow-12.1.0-pp311-pypy311_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:bb0984b30e973f7e2884362b7d23d0a348c7143ee559f38ef3eaab640144204c"},
- {file = "pillow-12.1.0-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:84cabc7095dd535ca934d57e9ce2a72ffd216e435a84acb06b2277b1de2689bd"},
- {file = "pillow-12.1.0-pp311-pypy311_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:53d8b764726d3af1a138dd353116f774e3862ec7e3794e0c8781e30db0f35dfc"},
- {file = "pillow-12.1.0-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5da841d81b1a05ef940a8567da92decaa15bc4d7dedb540a8c219ad83d91808a"},
- {file = "pillow-12.1.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:75af0b4c229ac519b155028fa1be632d812a519abba9b46b20e50c6caa184f19"},
- {file = "pillow-12.1.0.tar.gz", hash = "sha256:5c5ae0a06e9ea030ab786b0251b32c7e4ce10e58d983c0d5c56029455180b5b9"},
+ {file = "pillow-12.1.1-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:1f1625b72740fdda5d77b4def688eb8fd6490975d06b909fd19f13f391e077e0"},
+ {file = "pillow-12.1.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:178aa072084bd88ec759052feca8e56cbb14a60b39322b99a049e58090479713"},
+ {file = "pillow-12.1.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:b66e95d05ba806247aaa1561f080abc7975daf715c30780ff92a20e4ec546e1b"},
+ {file = "pillow-12.1.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:89c7e895002bbe49cdc5426150377cbbc04767d7547ed145473f496dfa40408b"},
+ {file = "pillow-12.1.1-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3a5cbdcddad0af3da87cb16b60d23648bc3b51967eb07223e9fed77a82b457c4"},
+ {file = "pillow-12.1.1-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9f51079765661884a486727f0729d29054242f74b46186026582b4e4769918e4"},
+ {file = "pillow-12.1.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:99c1506ea77c11531d75e3a412832a13a71c7ebc8192ab9e4b2e355555920e3e"},
+ {file = "pillow-12.1.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:36341d06738a9f66c8287cf8b876d24b18db9bd8740fa0672c74e259ad408cff"},
+ {file = "pillow-12.1.1-cp310-cp310-win32.whl", hash = "sha256:6c52f062424c523d6c4db85518774cc3d50f5539dd6eed32b8f6229b26f24d40"},
+ {file = "pillow-12.1.1-cp310-cp310-win_amd64.whl", hash = "sha256:c6008de247150668a705a6338156efb92334113421ceecf7438a12c9a12dab23"},
+ {file = "pillow-12.1.1-cp310-cp310-win_arm64.whl", hash = "sha256:1a9b0ee305220b392e1124a764ee4265bd063e54a751a6b62eff69992f457fa9"},
+ {file = "pillow-12.1.1-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:e879bb6cd5c73848ef3b2b48b8af9ff08c5b71ecda8048b7dd22d8a33f60be32"},
+ {file = "pillow-12.1.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:365b10bb9417dd4498c0e3b128018c4a624dc11c7b97d8cc54effe3b096f4c38"},
+ {file = "pillow-12.1.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:d4ce8e329c93845720cd2014659ca67eac35f6433fd3050393d85f3ecef0dad5"},
+ {file = "pillow-12.1.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:fc354a04072b765eccf2204f588a7a532c9511e8b9c7f900e1b64e3e33487090"},
+ {file = "pillow-12.1.1-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7e7976bf1910a8116b523b9f9f58bf410f3e8aa330cd9a2bb2953f9266ab49af"},
+ {file = "pillow-12.1.1-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:597bd9c8419bc7c6af5604e55847789b69123bbe25d65cc6ad3012b4f3c98d8b"},
+ {file = "pillow-12.1.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:2c1fc0f2ca5f96a3c8407e41cca26a16e46b21060fe6d5b099d2cb01412222f5"},
+ {file = "pillow-12.1.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:578510d88c6229d735855e1f278aa305270438d36a05031dfaae5067cc8eb04d"},
+ {file = "pillow-12.1.1-cp311-cp311-win32.whl", hash = "sha256:7311c0a0dcadb89b36b7025dfd8326ecfa36964e29913074d47382706e516a7c"},
+ {file = "pillow-12.1.1-cp311-cp311-win_amd64.whl", hash = "sha256:fbfa2a7c10cc2623f412753cddf391c7f971c52ca40a3f65dc5039b2939e8563"},
+ {file = "pillow-12.1.1-cp311-cp311-win_arm64.whl", hash = "sha256:b81b5e3511211631b3f672a595e3221252c90af017e399056d0faabb9538aa80"},
+ {file = "pillow-12.1.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:ab323b787d6e18b3d91a72fc99b1a2c28651e4358749842b8f8dfacd28ef2052"},
+ {file = "pillow-12.1.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:adebb5bee0f0af4909c30db0d890c773d1a92ffe83da908e2e9e720f8edf3984"},
+ {file = "pillow-12.1.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:bb66b7cc26f50977108790e2456b7921e773f23db5630261102233eb355a3b79"},
+ {file = "pillow-12.1.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:aee2810642b2898bb187ced9b349e95d2a7272930796e022efaf12e99dccd293"},
+ {file = "pillow-12.1.1-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a0b1cd6232e2b618adcc54d9882e4e662a089d5768cd188f7c245b4c8c44a397"},
+ {file = "pillow-12.1.1-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7aac39bcf8d4770d089588a2e1dd111cbaa42df5a94be3114222057d68336bd0"},
+ {file = "pillow-12.1.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:ab174cd7d29a62dd139c44bf74b698039328f45cb03b4596c43473a46656b2f3"},
+ {file = "pillow-12.1.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:339ffdcb7cbeaa08221cd401d517d4b1fe7a9ed5d400e4a8039719238620ca35"},
+ {file = "pillow-12.1.1-cp312-cp312-win32.whl", hash = "sha256:5d1f9575a12bed9e9eedd9a4972834b08c97a352bd17955ccdebfeca5913fa0a"},
+ {file = "pillow-12.1.1-cp312-cp312-win_amd64.whl", hash = "sha256:21329ec8c96c6e979cd0dfd29406c40c1d52521a90544463057d2aaa937d66a6"},
+ {file = "pillow-12.1.1-cp312-cp312-win_arm64.whl", hash = "sha256:af9a332e572978f0218686636610555ae3defd1633597be015ed50289a03c523"},
+ {file = "pillow-12.1.1-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:d242e8ac078781f1de88bf823d70c1a9b3c7950a44cdf4b7c012e22ccbcd8e4e"},
+ {file = "pillow-12.1.1-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:02f84dfad02693676692746df05b89cf25597560db2857363a208e393429f5e9"},
+ {file = "pillow-12.1.1-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:e65498daf4b583091ccbb2556c7000abf0f3349fcd57ef7adc9a84a394ed29f6"},
+ {file = "pillow-12.1.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:6c6db3b84c87d48d0088943bf33440e0c42370b99b1c2a7989216f7b42eede60"},
+ {file = "pillow-12.1.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:8b7e5304e34942bf62e15184219a7b5ad4ff7f3bb5cca4d984f37df1a0e1aee2"},
+ {file = "pillow-12.1.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:18e5bddd742a44b7e6b1e773ab5db102bd7a94c32555ba656e76d319d19c3850"},
+ {file = "pillow-12.1.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:fc44ef1f3de4f45b50ccf9136999d71abb99dca7706bc75d222ed350b9fd2289"},
+ {file = "pillow-12.1.1-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5a8eb7ed8d4198bccbd07058416eeec51686b498e784eda166395a23eb99138e"},
+ {file = "pillow-12.1.1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:47b94983da0c642de92ced1702c5b6c292a84bd3a8e1d1702ff923f183594717"},
+ {file = "pillow-12.1.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:518a48c2aab7ce596d3bf79d0e275661b846e86e4d0e7dec34712c30fe07f02a"},
+ {file = "pillow-12.1.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a550ae29b95c6dc13cf69e2c9dc5747f814c54eeb2e32d683e5e93af56caa029"},
+ {file = "pillow-12.1.1-cp313-cp313-win32.whl", hash = "sha256:a003d7422449f6d1e3a34e3dd4110c22148336918ddbfc6a32581cd54b2e0b2b"},
+ {file = "pillow-12.1.1-cp313-cp313-win_amd64.whl", hash = "sha256:344cf1e3dab3be4b1fa08e449323d98a2a3f819ad20f4b22e77a0ede31f0faa1"},
+ {file = "pillow-12.1.1-cp313-cp313-win_arm64.whl", hash = "sha256:5c0dd1636633e7e6a0afe7bf6a51a14992b7f8e60de5789018ebbdfae55b040a"},
+ {file = "pillow-12.1.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:0330d233c1a0ead844fc097a7d16c0abff4c12e856c0b325f231820fee1f39da"},
+ {file = "pillow-12.1.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:5dae5f21afb91322f2ff791895ddd8889e5e947ff59f71b46041c8ce6db790bc"},
+ {file = "pillow-12.1.1-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:2e0c664be47252947d870ac0d327fea7e63985a08794758aa8af5b6cb6ec0c9c"},
+ {file = "pillow-12.1.1-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:691ab2ac363b8217f7d31b3497108fb1f50faab2f75dfb03284ec2f217e87bf8"},
+ {file = "pillow-12.1.1-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e9e8064fb1cc019296958595f6db671fba95209e3ceb0c4734c9baf97de04b20"},
+ {file = "pillow-12.1.1-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:472a8d7ded663e6162dafdf20015c486a7009483ca671cece7a9279b512fcb13"},
+ {file = "pillow-12.1.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:89b54027a766529136a06cfebeecb3a04900397a3590fd252160b888479517bf"},
+ {file = "pillow-12.1.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:86172b0831b82ce4f7877f280055892b31179e1576aa00d0df3bb1bbf8c3e524"},
+ {file = "pillow-12.1.1-cp313-cp313t-win32.whl", hash = "sha256:44ce27545b6efcf0fdbdceb31c9a5bdea9333e664cda58a7e674bb74608b3986"},
+ {file = "pillow-12.1.1-cp313-cp313t-win_amd64.whl", hash = "sha256:a285e3eb7a5a45a2ff504e31f4a8d1b12ef62e84e5411c6804a42197c1cf586c"},
+ {file = "pillow-12.1.1-cp313-cp313t-win_arm64.whl", hash = "sha256:cc7d296b5ea4d29e6570dabeaed58d31c3fea35a633a69679fb03d7664f43fb3"},
+ {file = "pillow-12.1.1-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:417423db963cb4be8bac3fc1204fe61610f6abeed1580a7a2cbb2fbda20f12af"},
+ {file = "pillow-12.1.1-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:b957b71c6b2387610f556a7eb0828afbe40b4a98036fc0d2acfa5a44a0c2036f"},
+ {file = "pillow-12.1.1-cp314-cp314-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:097690ba1f2efdeb165a20469d59d8bb03c55fb6621eb2041a060ae8ea3e9642"},
+ {file = "pillow-12.1.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:2815a87ab27848db0321fb78c7f0b2c8649dee134b7f2b80c6a45c6831d75ccd"},
+ {file = "pillow-12.1.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:f7ed2c6543bad5a7d5530eb9e78c53132f93dfa44a28492db88b41cdab885202"},
+ {file = "pillow-12.1.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:652a2c9ccfb556235b2b501a3a7cf3742148cd22e04b5625c5fe057ea3e3191f"},
+ {file = "pillow-12.1.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d6e4571eedf43af33d0fc233a382a76e849badbccdf1ac438841308652a08e1f"},
+ {file = "pillow-12.1.1-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b574c51cf7d5d62e9be37ba446224b59a2da26dc4c1bb2ecbe936a4fb1a7cb7f"},
+ {file = "pillow-12.1.1-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a37691702ed687799de29a518d63d4682d9016932db66d4e90c345831b02fb4e"},
+ {file = "pillow-12.1.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:f95c00d5d6700b2b890479664a06e754974848afaae5e21beb4d83c106923fd0"},
+ {file = "pillow-12.1.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:559b38da23606e68681337ad74622c4dbba02254fc9cb4488a305dd5975c7eeb"},
+ {file = "pillow-12.1.1-cp314-cp314-win32.whl", hash = "sha256:03edcc34d688572014ff223c125a3f77fb08091e4607e7745002fc214070b35f"},
+ {file = "pillow-12.1.1-cp314-cp314-win_amd64.whl", hash = "sha256:50480dcd74fa63b8e78235957d302d98d98d82ccbfac4c7e12108ba9ecbdba15"},
+ {file = "pillow-12.1.1-cp314-cp314-win_arm64.whl", hash = "sha256:5cb1785d97b0c3d1d1a16bc1d710c4a0049daefc4935f3a8f31f827f4d3d2e7f"},
+ {file = "pillow-12.1.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:1f90cff8aa76835cba5769f0b3121a22bd4eb9e6884cfe338216e557a9a548b8"},
+ {file = "pillow-12.1.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:1f1be78ce9466a7ee64bfda57bdba0f7cc499d9794d518b854816c41bf0aa4e9"},
+ {file = "pillow-12.1.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:42fc1f4677106188ad9a55562bbade416f8b55456f522430fadab3cef7cd4e60"},
+ {file = "pillow-12.1.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:98edb152429ab62a1818039744d8fbb3ccab98a7c29fc3d5fcef158f3f1f68b7"},
+ {file = "pillow-12.1.1-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d470ab1178551dd17fdba0fef463359c41aaa613cdcd7ff8373f54be629f9f8f"},
+ {file = "pillow-12.1.1-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6408a7b064595afcab0a49393a413732a35788f2a5092fdc6266952ed67de586"},
+ {file = "pillow-12.1.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:5d8c41325b382c07799a3682c1c258469ea2ff97103c53717b7893862d0c98ce"},
+ {file = "pillow-12.1.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:c7697918b5be27424e9ce568193efd13d925c4481dd364e43f5dff72d33e10f8"},
+ {file = "pillow-12.1.1-cp314-cp314t-win32.whl", hash = "sha256:d2912fd8114fc5545aa3a4b5576512f64c55a03f3ebcca4c10194d593d43ea36"},
+ {file = "pillow-12.1.1-cp314-cp314t-win_amd64.whl", hash = "sha256:4ceb838d4bd9dab43e06c363cab2eebf63846d6a4aeaea283bbdfd8f1a8ed58b"},
+ {file = "pillow-12.1.1-cp314-cp314t-win_arm64.whl", hash = "sha256:7b03048319bfc6170e93bd60728a1af51d3dd7704935feb228c4d4faab35d334"},
+ {file = "pillow-12.1.1-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:600fd103672b925fe62ed08e0d874ea34d692474df6f4bf7ebe148b30f89f39f"},
+ {file = "pillow-12.1.1-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:665e1b916b043cef294bc54d47bf02d87e13f769bc4bc5fa225a24b3a6c5aca9"},
+ {file = "pillow-12.1.1-pp311-pypy311_pp73-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:495c302af3aad1ca67420ddd5c7bd480c8867ad173528767d906428057a11f0e"},
+ {file = "pillow-12.1.1-pp311-pypy311_pp73-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:8fd420ef0c52c88b5a035a0886f367748c72147b2b8f384c9d12656678dfdfa9"},
+ {file = "pillow-12.1.1-pp311-pypy311_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f975aa7ef9684ce7e2c18a3aa8f8e2106ce1e46b94ab713d156b2898811651d3"},
+ {file = "pillow-12.1.1-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8089c852a56c2966cf18835db62d9b34fef7ba74c726ad943928d494fa7f4735"},
+ {file = "pillow-12.1.1-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:cb9bb857b2d057c6dfc72ac5f3b44836924ba15721882ef103cecb40d002d80e"},
+ {file = "pillow-12.1.1.tar.gz", hash = "sha256:9ad8fa5937ab05218e2b6a4cff30295ad35afd2f83ac592e68c0d871bb0fdbc4"},
]
[package.extras]
@@ -6660,7 +6626,7 @@ files = [
[[package]]
name = "prowler"
-version = "5.18.0"
+version = "5.19.0"
description = "Prowler is an Open Source security tool to perform AWS, GCP and Azure security best practices assessments, audits, incident response, continuous monitoring, hardening and forensics readiness. It contains hundreds of controls covering CIS, NIST 800, NIST CSF, CISA, RBI, FedRAMP, PCI-DSS, GDPR, HIPAA, FFIEC, SOC2, GXP, AWS Well-Architected Framework Security Pillar, AWS Foundational Technical Review (FTR), ENS (Spanish National Security Scheme) and your custom security frameworks."
optional = false
python-versions = ">3.9.1,<3.13"
@@ -6715,7 +6681,7 @@ boto3 = "1.40.61"
botocore = "1.40.61"
cloudflare = "4.3.1"
colorama = "0.4.6"
-cryptography = "44.0.1"
+cryptography = "44.0.3"
dash = "3.1.1"
dash-bootstrap-components = "2.0.3"
detect-secrets = "1.5.0"
@@ -6730,10 +6696,10 @@ microsoft-kiota-abstractions = "1.9.2"
msgraph-sdk = "1.23.0"
numpy = "2.0.2"
oci = "2.160.3"
-openstacksdk = "4.0.1"
+openstacksdk = "4.2.0"
pandas = "2.2.3"
py-iam-expand = "0.1.0"
-py-ocsf-models = "0.5.0"
+py-ocsf-models = "0.8.1"
pydantic = ">=2.0,<3.0"
pygithub = "2.5.0"
python-dateutil = ">=2.9.0.post0,<3.0.0"
@@ -6748,7 +6714,7 @@ tzlocal = "5.3.1"
type = "git"
url = "https://github.com/prowler-cloud/prowler.git"
reference = "master"
-resolved_reference = "b1f99716171856bf787a7695a588ffad6bf8d596"
+resolved_reference = "ceb4691c3657e7db3d178896bfc241d14f194295"
[[package]]
name = "psutil"
@@ -6896,20 +6862,20 @@ iamdata = ">=0.1.202504091"
[[package]]
name = "py-ocsf-models"
-version = "0.5.0"
+version = "0.8.1"
description = "This is a Python implementation of the OCSF models. The models are used to represent the data of the OCSF Schema defined in https://schema.ocsf.io/."
optional = false
-python-versions = "<3.14,>3.9.1"
+python-versions = "<3.15,>3.9.1"
groups = ["main"]
files = [
- {file = "py_ocsf_models-0.5.0-py3-none-any.whl", hash = "sha256:7933253f56782c04c412d976796db429577810b951fe4195351794500b5962d8"},
- {file = "py_ocsf_models-0.5.0.tar.gz", hash = "sha256:bf05e955809d1ec3ab1007e4a4b2a8a0afa74b6e744ea8ffbf386e46b3af0a76"},
+ {file = "py_ocsf_models-0.8.1-py3-none-any.whl", hash = "sha256:061eb446c4171534c09a8b37f5a9d2a2fe9f87c5db32edbd1182446bc5fd097e"},
+ {file = "py_ocsf_models-0.8.1.tar.gz", hash = "sha256:c9045237857f951e073c9f9d1f57954c90d86875b469260725292d47f7a7d73c"},
]
[package.dependencies]
-cryptography = "44.0.1"
+cryptography = ">=44.0.3,<47"
email-validator = "2.2.0"
-pydantic = ">=2.9.2,<3.0.0"
+pydantic = ">=2.12.0,<3.0.0"
[[package]]
name = "pyasn1"
@@ -9400,4 +9366,4 @@ files = [
[metadata]
lock-version = "2.1"
python-versions = ">=3.11,<3.13"
-content-hash = "bada7223d576ddd48ff74aa101d18e7465492cf014006e17354dbe2190a02b29"
+content-hash = "c575bc849038db5b5d0882bec441529bf474a42b28c96718372ad4ceb388432c"
diff --git a/api/pyproject.toml b/api/pyproject.toml
index e0f577e076..5f5c5444d1 100644
--- a/api/pyproject.toml
+++ b/api/pyproject.toml
@@ -24,7 +24,7 @@ dependencies = [
"drf-spectacular-jsonapi==0.5.1",
"gunicorn==23.0.0",
"lxml==5.3.2",
- "prowler @ git+https://github.com/prowler-cloud/prowler.git@master",
+ "prowler @ git+https://github.com/prowler-cloud/prowler.git@feat/PROWLER-940-stage-2-a-image-provider-api-v3",
"psycopg2-binary==2.9.9",
"pytest-celery[redis] (>=1.0.1,<2.0.0)",
"sentry-sdk[django] (>=2.20.0,<3.0.0)",
diff --git a/api/src/backend/api/attack_paths/queries/aws.py b/api/src/backend/api/attack_paths/queries/aws.py
index 60208b7e51..39e5e5716f 100644
--- a/api/src/backend/api/attack_paths/queries/aws.py
+++ b/api/src/backend/api/attack_paths/queries/aws.py
@@ -1,17 +1,18 @@
from api.attack_paths.queries.types import (
+ AttackPathsQueryAttribution,
AttackPathsQueryDefinition,
AttackPathsQueryParameterDefinition,
)
from tasks.jobs.attack_paths.config import PROWLER_FINDING_LABEL
-# Privilege Escalation Queries (based on pathfinding.cloud research)
-# https://github.com/DataDog/pathfinding.cloud
-# -------------------------------------------------------------------
+# Custom Attack Path Queries
+# --------------------------
AWS_INTERNET_EXPOSED_EC2_SENSITIVE_S3_ACCESS = AttackPathsQueryDefinition(
id="aws-internet-exposed-ec2-sensitive-s3-access",
- name="Identify internet-exposed EC2 instances with sensitive S3 access",
+ name="Internet-Exposed EC2 with Sensitive S3 Access",
+ short_description="Find SSH-exposed EC2 instances that can assume roles to read tagged sensitive S3 buckets.",
description="Detect EC2 instances with SSH exposed to the internet that can assume higher-privileged roles to read tagged sensitive S3 buckets despite bucket-level public access blocks.",
provider="aws",
cypher=f"""
@@ -35,8 +36,7 @@ AWS_INTERNET_EXPOSED_EC2_SENSITIVE_S3_ACCESS = AttackPathsQueryDefinition(
YIELD rel AS can_access
UNWIND nodes(path_s3) + nodes(path_ec2) + nodes(path_role) + nodes(path_assume_role) as n
- OPTIONAL MATCH (n)-[pfr]-(pf:{PROWLER_FINDING_LABEL})
- WHERE pf.status = 'FAIL'
+ OPTIONAL MATCH (n)-[pfr]-(pf:{PROWLER_FINDING_LABEL} {{status: 'FAIL', provider_uid: $provider_uid}})
RETURN path_s3, path_ec2, path_role, path_assume_role, collect(DISTINCT pf) as dpf, collect(DISTINCT pfr) as dpfr, internet, can_access
""",
@@ -62,15 +62,15 @@ AWS_INTERNET_EXPOSED_EC2_SENSITIVE_S3_ACCESS = AttackPathsQueryDefinition(
AWS_RDS_INSTANCES = AttackPathsQueryDefinition(
id="aws-rds-instances",
- name="Identify provisioned RDS instances",
+ name="RDS Instances Inventory",
+ short_description="List all provisioned RDS database instances in the account.",
description="List the selected AWS account alongside the RDS instances it owns.",
provider="aws",
cypher=f"""
MATCH path = (aws:AWSAccount {{id: $provider_uid}})--(rds:RDSInstance)
UNWIND nodes(path) as n
- OPTIONAL MATCH (n)-[pfr]-(pf:{PROWLER_FINDING_LABEL})
- WHERE pf.status = 'FAIL'
+ OPTIONAL MATCH (n)-[pfr]-(pf:{PROWLER_FINDING_LABEL} {{status: 'FAIL', provider_uid: $provider_uid}})
RETURN path, collect(DISTINCT pf) as dpf, collect(DISTINCT pfr) as dpfr
""",
@@ -79,7 +79,8 @@ AWS_RDS_INSTANCES = AttackPathsQueryDefinition(
AWS_RDS_UNENCRYPTED_STORAGE = AttackPathsQueryDefinition(
id="aws-rds-unencrypted-storage",
- name="Identify RDS instances without storage encryption",
+ name="Unencrypted RDS Instances",
+ short_description="Find RDS instances with storage encryption disabled.",
description="Find RDS instances with storage encryption disabled within the selected account.",
provider="aws",
cypher=f"""
@@ -87,8 +88,7 @@ AWS_RDS_UNENCRYPTED_STORAGE = AttackPathsQueryDefinition(
WHERE rds.storage_encrypted = false
UNWIND nodes(path) as n
- OPTIONAL MATCH (n)-[pfr]-(pf:{PROWLER_FINDING_LABEL})
- WHERE pf.status = 'FAIL'
+ OPTIONAL MATCH (n)-[pfr]-(pf:{PROWLER_FINDING_LABEL} {{status: 'FAIL', provider_uid: $provider_uid}})
RETURN path, collect(DISTINCT pf) as dpf, collect(DISTINCT pfr) as dpfr
""",
@@ -97,7 +97,8 @@ AWS_RDS_UNENCRYPTED_STORAGE = AttackPathsQueryDefinition(
AWS_S3_ANONYMOUS_ACCESS_BUCKETS = AttackPathsQueryDefinition(
id="aws-s3-anonymous-access-buckets",
- name="Identify S3 buckets with anonymous access",
+ name="S3 Buckets with Anonymous Access",
+ short_description="Find S3 buckets that allow anonymous access.",
description="Find S3 buckets that allow anonymous access within the selected account.",
provider="aws",
cypher=f"""
@@ -105,8 +106,7 @@ AWS_S3_ANONYMOUS_ACCESS_BUCKETS = AttackPathsQueryDefinition(
WHERE s3.anonymous_access = true
UNWIND nodes(path) as n
- OPTIONAL MATCH (n)-[pfr]-(pf:{PROWLER_FINDING_LABEL})
- WHERE pf.status = 'FAIL'
+ OPTIONAL MATCH (n)-[pfr]-(pf:{PROWLER_FINDING_LABEL} {{status: 'FAIL', provider_uid: $provider_uid}})
RETURN path, collect(DISTINCT pf) as dpf, collect(DISTINCT pfr) as dpfr
""",
@@ -115,7 +115,8 @@ AWS_S3_ANONYMOUS_ACCESS_BUCKETS = AttackPathsQueryDefinition(
AWS_IAM_STATEMENTS_ALLOW_ALL_ACTIONS = AttackPathsQueryDefinition(
id="aws-iam-statements-allow-all-actions",
- name="Identify IAM statements that allow all actions",
+ name="IAM Statements Allowing All Actions",
+ short_description="Find IAM policy statements that allow all actions via wildcard (*).",
description="Find IAM policy statements that allow all actions via '*' within the selected account.",
provider="aws",
cypher=f"""
@@ -124,8 +125,7 @@ AWS_IAM_STATEMENTS_ALLOW_ALL_ACTIONS = AttackPathsQueryDefinition(
AND any(x IN stmt.action WHERE x = '*')
UNWIND nodes(path) as n
- OPTIONAL MATCH (n)-[pfr]-(pf:{PROWLER_FINDING_LABEL})
- WHERE pf.status = 'FAIL'
+ OPTIONAL MATCH (n)-[pfr]-(pf:{PROWLER_FINDING_LABEL} {{status: 'FAIL', provider_uid: $provider_uid}})
RETURN path, collect(DISTINCT pf) as dpf, collect(DISTINCT pfr) as dpfr
""",
@@ -134,7 +134,8 @@ AWS_IAM_STATEMENTS_ALLOW_ALL_ACTIONS = AttackPathsQueryDefinition(
AWS_IAM_STATEMENTS_ALLOW_DELETE_POLICY = AttackPathsQueryDefinition(
id="aws-iam-statements-allow-delete-policy",
- name="Identify IAM statements that allow iam:DeletePolicy",
+ name="IAM Statements Allowing Policy Deletion",
+ short_description="Find IAM policy statements that allow iam:DeletePolicy.",
description="Find IAM policy statements that allow the iam:DeletePolicy action within the selected account.",
provider="aws",
cypher=f"""
@@ -143,8 +144,7 @@ AWS_IAM_STATEMENTS_ALLOW_DELETE_POLICY = AttackPathsQueryDefinition(
AND any(x IN stmt.action WHERE x = "iam:DeletePolicy")
UNWIND nodes(path) as n
- OPTIONAL MATCH (n)-[pfr]-(pf:{PROWLER_FINDING_LABEL})
- WHERE pf.status = 'FAIL'
+ OPTIONAL MATCH (n)-[pfr]-(pf:{PROWLER_FINDING_LABEL} {{status: 'FAIL', provider_uid: $provider_uid}})
RETURN path, collect(DISTINCT pf) as dpf, collect(DISTINCT pfr) as dpfr
""",
@@ -153,7 +153,8 @@ AWS_IAM_STATEMENTS_ALLOW_DELETE_POLICY = AttackPathsQueryDefinition(
AWS_IAM_STATEMENTS_ALLOW_CREATE_ACTIONS = AttackPathsQueryDefinition(
id="aws-iam-statements-allow-create-actions",
- name="Identify IAM statements that allow create actions",
+ name="IAM Statements Allowing Create Actions",
+ short_description="Find IAM policy statements that allow any create action.",
description="Find IAM policy statements that allow actions containing 'create' within the selected account.",
provider="aws",
cypher=f"""
@@ -162,8 +163,7 @@ AWS_IAM_STATEMENTS_ALLOW_CREATE_ACTIONS = AttackPathsQueryDefinition(
AND any(x IN stmt.action WHERE toLower(x) CONTAINS "create")
UNWIND nodes(path) as n
- OPTIONAL MATCH (n)-[pfr]-(pf:{PROWLER_FINDING_LABEL})
- WHERE pf.status = 'FAIL'
+ OPTIONAL MATCH (n)-[pfr]-(pf:{PROWLER_FINDING_LABEL} {{status: 'FAIL', provider_uid: $provider_uid}})
RETURN path, collect(DISTINCT pf) as dpf, collect(DISTINCT pfr) as dpfr
""",
@@ -176,7 +176,8 @@ AWS_IAM_STATEMENTS_ALLOW_CREATE_ACTIONS = AttackPathsQueryDefinition(
AWS_EC2_INSTANCES_INTERNET_EXPOSED = AttackPathsQueryDefinition(
id="aws-ec2-instances-internet-exposed",
- name="Identify internet-exposed EC2 instances",
+ name="Internet-Exposed EC2 Instances",
+ short_description="Find EC2 instances flagged as exposed to the internet.",
description="Find EC2 instances flagged as exposed to the internet within the selected account.",
provider="aws",
cypher=f"""
@@ -190,8 +191,7 @@ AWS_EC2_INSTANCES_INTERNET_EXPOSED = AttackPathsQueryDefinition(
YIELD rel AS can_access
UNWIND nodes(path) as n
- OPTIONAL MATCH (n)-[pfr]-(pf:{PROWLER_FINDING_LABEL})
- WHERE pf.status = 'FAIL'
+ OPTIONAL MATCH (n)-[pfr]-(pf:{PROWLER_FINDING_LABEL} {{status: 'FAIL', provider_uid: $provider_uid}})
RETURN path, collect(DISTINCT pf) as dpf, collect(DISTINCT pfr) as dpfr, internet, can_access
""",
@@ -200,7 +200,8 @@ AWS_EC2_INSTANCES_INTERNET_EXPOSED = AttackPathsQueryDefinition(
AWS_SECURITY_GROUPS_OPEN_INTERNET_FACING = AttackPathsQueryDefinition(
id="aws-security-groups-open-internet-facing",
- name="Identify internet-facing resources with open security groups",
+ name="Open Security Groups on Internet-Facing Resources",
+ short_description="Find internet-facing resources with security groups allowing inbound from 0.0.0.0/0.",
description="Find internet-facing resources associated with security groups that allow inbound access from '0.0.0.0/0'.",
provider="aws",
cypher=f"""
@@ -216,8 +217,7 @@ AWS_SECURITY_GROUPS_OPEN_INTERNET_FACING = AttackPathsQueryDefinition(
YIELD rel AS can_access
UNWIND nodes(path_ec2) as n
- OPTIONAL MATCH (n)-[pfr]-(pf:{PROWLER_FINDING_LABEL})
- WHERE pf.status = 'FAIL'
+ OPTIONAL MATCH (n)-[pfr]-(pf:{PROWLER_FINDING_LABEL} {{status: 'FAIL', provider_uid: $provider_uid}})
RETURN path_ec2, collect(DISTINCT pf) as dpf, collect(DISTINCT pfr) as dpfr, internet, can_access
""",
@@ -226,7 +226,8 @@ AWS_SECURITY_GROUPS_OPEN_INTERNET_FACING = AttackPathsQueryDefinition(
AWS_CLASSIC_ELB_INTERNET_EXPOSED = AttackPathsQueryDefinition(
id="aws-classic-elb-internet-exposed",
- name="Identify internet-exposed Classic Load Balancers",
+ name="Internet-Exposed Classic Load Balancers",
+ short_description="Find Classic Load Balancers exposed to the internet with their listeners.",
description="Find Classic Load Balancers exposed to the internet along with their listeners.",
provider="aws",
cypher=f"""
@@ -240,8 +241,7 @@ AWS_CLASSIC_ELB_INTERNET_EXPOSED = AttackPathsQueryDefinition(
YIELD rel AS can_access
UNWIND nodes(path) as n
- OPTIONAL MATCH (n)-[pfr]-(pf:{PROWLER_FINDING_LABEL})
- WHERE pf.status = 'FAIL'
+ OPTIONAL MATCH (n)-[pfr]-(pf:{PROWLER_FINDING_LABEL} {{status: 'FAIL', provider_uid: $provider_uid}})
RETURN path, collect(DISTINCT pf) as dpf, collect(DISTINCT pfr) as dpfr, internet, can_access
""",
@@ -250,7 +250,8 @@ AWS_CLASSIC_ELB_INTERNET_EXPOSED = AttackPathsQueryDefinition(
AWS_ELBV2_INTERNET_EXPOSED = AttackPathsQueryDefinition(
id="aws-elbv2-internet-exposed",
- name="Identify internet-exposed ELBv2 load balancers",
+ name="Internet-Exposed ALB/NLB Load Balancers",
+ short_description="Find ELBv2 (ALB/NLB) load balancers exposed to the internet with their listeners.",
description="Find ELBv2 load balancers exposed to the internet along with their listeners.",
provider="aws",
cypher=f"""
@@ -264,8 +265,7 @@ AWS_ELBV2_INTERNET_EXPOSED = AttackPathsQueryDefinition(
YIELD rel AS can_access
UNWIND nodes(path) as n
- OPTIONAL MATCH (n)-[pfr]-(pf:{PROWLER_FINDING_LABEL})
- WHERE pf.status = 'FAIL'
+ OPTIONAL MATCH (n)-[pfr]-(pf:{PROWLER_FINDING_LABEL} {{status: 'FAIL', provider_uid: $provider_uid}})
RETURN path, collect(DISTINCT pf) as dpf, collect(DISTINCT pfr) as dpfr, internet, can_access
""",
@@ -274,7 +274,8 @@ AWS_ELBV2_INTERNET_EXPOSED = AttackPathsQueryDefinition(
AWS_PUBLIC_IP_RESOURCE_LOOKUP = AttackPathsQueryDefinition(
id="aws-public-ip-resource-lookup",
- name="Identify resources by public IP address",
+ name="Resource Lookup by Public IP",
+ short_description="Find the AWS resource associated with a given public IP address.",
description="Given a public IP address, find the related AWS resource and its adjacent node within the selected account.",
provider="aws",
cypher=f"""
@@ -305,8 +306,7 @@ AWS_PUBLIC_IP_RESOURCE_LOOKUP = AttackPathsQueryDefinition(
YIELD rel AS can_access
UNWIND nodes(path) as n
- OPTIONAL MATCH (n)-[pfr]-(pf:{PROWLER_FINDING_LABEL})
- WHERE pf.status = 'FAIL'
+ OPTIONAL MATCH (n)-[pfr]-(pf:{PROWLER_FINDING_LABEL} {{status: 'FAIL', provider_uid: $provider_uid}})
RETURN path, collect(DISTINCT pf) as dpf, collect(DISTINCT pfr) as dpfr, internet, can_access
""",
@@ -320,38 +320,24 @@ AWS_PUBLIC_IP_RESOURCE_LOOKUP = AttackPathsQueryDefinition(
],
)
+# Privilege Escalation Queries (based on pathfinding.cloud research)
+# https://github.com/DataDog/pathfinding.cloud
+# -------------------------------------------------------------------
-AWS_IAM_PRIVESC_PASSROLE_EC2 = AttackPathsQueryDefinition(
- id="aws-iam-privesc-passrole-ec2",
- name="Privilege Escalation: iam:PassRole + ec2:RunInstances",
- description="Detect principals who can launch EC2 instances with privileged IAM roles attached. This allows gaining the permissions of the passed role by accessing the EC2 instance metadata service. This is a new-passrole escalation path (pathfinding.cloud: ec2-001).",
+# APPRUNNER-001
+AWS_APPRUNNER_PRIVESC_PASSROLE_CREATE_SERVICE = AttackPathsQueryDefinition(
+ id="aws-apprunner-privesc-passrole-create-service",
+ name="App Runner Service Creation with Privileged Role (APPRUNNER-001)",
+ short_description="Create an App Runner service with a privileged IAM role to gain its permissions.",
+ description="Detect principals who can pass IAM roles and create App Runner services. This allows creating a service with a privileged role attached, gaining that role's permissions via StartCommand execution, a container web shell, or a malicious apprunner.yaml configuration.",
+ attribution=AttackPathsQueryAttribution(
+ text="pathfinding.cloud - APPRUNNER-001 - iam:PassRole + apprunner:CreateService",
+ link="https://pathfinding.cloud/paths/apprunner-001",
+ ),
provider="aws",
cypher=f"""
- // Create a single shared virtual EC2 instance node
- CALL apoc.create.vNode(['EC2Instance'], {{
- id: 'potential-ec2-passrole',
- name: 'New EC2 Instance',
- description: 'Attacker-controlled EC2 with privileged role'
- }})
- YIELD node AS ec2_node
-
- // Create a single shared virtual escalation outcome node (styled like a finding)
- CALL apoc.create.vNode(['PrivilegeEscalation'], {{
- id: 'effective-administrator-passrole-ec2',
- check_title: 'Privilege Escalation',
- name: 'Effective Administrator',
- status: 'FAIL',
- severity: 'critical'
- }})
- YIELD node AS escalation_outcome
-
- WITH ec2_node, escalation_outcome
-
- // Find principals in the account
- MATCH path_principal = (aws:AWSAccount {{id: $provider_uid}})--(principal:AWSPrincipal)
-
- // Find statements granting iam:PassRole
- MATCH path_passrole = (principal)--(passrole_policy:AWSPolicy)--(stmt_passrole:AWSPolicyStatement)
+ // Find principals with iam:PassRole permission
+ MATCH path_principal = (aws:AWSAccount {{id: $provider_uid}})--(principal:AWSPrincipal)--(passrole_policy:AWSPolicy)--(stmt_passrole:AWSPolicyStatement)
WHERE stmt_passrole.effect = 'Allow'
AND any(action IN stmt_passrole.action WHERE
toLower(action) = 'iam:passrole'
@@ -359,8 +345,664 @@ AWS_IAM_PRIVESC_PASSROLE_EC2 = AttackPathsQueryDefinition(
OR action = '*'
)
- // Find statements granting ec2:RunInstances
- MATCH path_ec2 = (principal)--(ec2_policy:AWSPolicy)--(stmt_ec2:AWSPolicyStatement)
+ // Find apprunner:CreateService permission
+ MATCH (principal)--(apprunner_policy:AWSPolicy)--(stmt_apprunner:AWSPolicyStatement)
+ WHERE stmt_apprunner.effect = 'Allow'
+ AND any(action IN stmt_apprunner.action WHERE
+ toLower(action) = 'apprunner:createservice'
+ OR toLower(action) = 'apprunner:*'
+ OR action = '*'
+ )
+
+ // Find roles that trust App Runner tasks service (can be passed to App Runner)
+ MATCH path_target = (aws)--(target_role:AWSRole)-[:TRUSTS_AWS_PRINCIPAL]->(:AWSPrincipal {{arn: 'tasks.apprunner.amazonaws.com'}})
+ WHERE any(resource IN stmt_passrole.resource WHERE
+ resource = '*'
+ OR target_role.arn CONTAINS resource
+ OR resource CONTAINS target_role.name
+ )
+
+ UNWIND nodes(path_principal) + nodes(path_target) as n
+ OPTIONAL MATCH (n)-[pfr]-(pf:{PROWLER_FINDING_LABEL} {{status: 'FAIL', provider_uid: $provider_uid}})
+
+ RETURN path_principal, path_target,
+ collect(DISTINCT pf) as dpf, collect(DISTINCT pfr) as dpfr
+ """,
+ parameters=[],
+)
+
+# APPRUNNER-002
+AWS_APPRUNNER_PRIVESC_UPDATE_SERVICE = AttackPathsQueryDefinition(
+ id="aws-apprunner-privesc-update-service",
+ name="App Runner Service Update for Role Access (APPRUNNER-002)",
+ short_description="Update an existing App Runner service to leverage its already-attached privileged role.",
+ description="Detect principals who can update existing App Runner services. This allows modifying a service's configuration to execute arbitrary code with the service's already-attached IAM role, without requiring iam:PassRole. Exploitation methods include injecting a malicious StartCommand, updating to a container image with a web shell, or pointing to a repository with a malicious apprunner.yaml file.",
+ attribution=AttackPathsQueryAttribution(
+ text="pathfinding.cloud - APPRUNNER-002 - apprunner:UpdateService",
+ link="https://pathfinding.cloud/paths/apprunner-002",
+ ),
+ provider="aws",
+ cypher=f"""
+ // Find principals with apprunner:UpdateService permission
+ MATCH path_principal = (aws:AWSAccount {{id: $provider_uid}})--(principal:AWSPrincipal)--(update_policy:AWSPolicy)--(stmt_update:AWSPolicyStatement)
+ WHERE stmt_update.effect = 'Allow'
+ AND any(action IN stmt_update.action WHERE
+ toLower(action) = 'apprunner:updateservice'
+ OR toLower(action) = 'apprunner:*'
+ OR action = '*'
+ )
+
+ // Find existing App Runner services with roles attached (potential targets)
+ MATCH path_target = (aws)--(target_role:AWSRole)-[:TRUSTS_AWS_PRINCIPAL]->(:AWSPrincipal {{arn: 'tasks.apprunner.amazonaws.com'}})
+
+ UNWIND nodes(path_principal) + nodes(path_target) as n
+ OPTIONAL MATCH (n)-[pfr]-(pf:{PROWLER_FINDING_LABEL} {{status: 'FAIL', provider_uid: $provider_uid}})
+
+ RETURN path_principal, path_target,
+ collect(DISTINCT pf) as dpf, collect(DISTINCT pfr) as dpfr
+ """,
+ parameters=[],
+)
+
+# BEDROCK-001
+AWS_BEDROCK_PRIVESC_PASSROLE_CODE_INTERPRETER = AttackPathsQueryDefinition(
+ id="aws-bedrock-privesc-passrole-code-interpreter",
+ name="Bedrock Code Interpreter with Privileged Role (BEDROCK-001)",
+ short_description="Create a Bedrock AgentCore Code Interpreter with a privileged role attached.",
+ description="Detect principals who can pass IAM roles and create Bedrock AgentCore Code Interpreters. This allows creating a code interpreter with a privileged role attached, gaining that role's permissions.",
+ attribution=AttackPathsQueryAttribution(
+ text="pathfinding.cloud - BEDROCK-001 - iam:PassRole + bedrock-agentcore:CreateCodeInterpreter + bedrock-agentcore:StartCodeInterpreterSession + bedrock-agentcore:InvokeCodeInterpreter",
+ link="https://pathfinding.cloud/paths/bedrock-001",
+ ),
+ provider="aws",
+ cypher=f"""
+ // Find principals with iam:PassRole permission
+ MATCH path_principal = (aws:AWSAccount {{id: $provider_uid}})--(principal:AWSPrincipal)--(passrole_policy:AWSPolicy)--(stmt_passrole:AWSPolicyStatement)
+ WHERE stmt_passrole.effect = 'Allow'
+ AND any(action IN stmt_passrole.action WHERE
+ toLower(action) = 'iam:passrole'
+ OR toLower(action) = 'iam:*'
+ OR action = '*'
+ )
+
+ // Find bedrock-agentcore:CreateCodeInterpreter permission
+ MATCH (principal)--(bedrock_policy:AWSPolicy)--(stmt_bedrock:AWSPolicyStatement)
+ WHERE stmt_bedrock.effect = 'Allow'
+ AND any(action IN stmt_bedrock.action WHERE
+ toLower(action) = 'bedrock-agentcore:createcodeinterpreter'
+ OR toLower(action) = 'bedrock-agentcore:*'
+ OR action = '*'
+ )
+
+ // Find bedrock-agentcore:StartCodeInterpreterSession permission
+ MATCH (principal)--(session_policy:AWSPolicy)--(stmt_session:AWSPolicyStatement)
+ WHERE stmt_session.effect = 'Allow'
+ AND any(action IN stmt_session.action WHERE
+ toLower(action) = 'bedrock-agentcore:startcodeinterpretersession'
+ OR toLower(action) = 'bedrock-agentcore:*'
+ OR action = '*'
+ )
+
+ // Find bedrock-agentcore:InvokeCodeInterpreter permission
+ MATCH (principal)--(invoke_policy:AWSPolicy)--(stmt_invoke:AWSPolicyStatement)
+ WHERE stmt_invoke.effect = 'Allow'
+ AND any(action IN stmt_invoke.action WHERE
+ toLower(action) = 'bedrock-agentcore:invokecodeinterpreter'
+ OR toLower(action) = 'bedrock-agentcore:*'
+ OR action = '*'
+ )
+
+ // Find roles that trust Bedrock service (can be passed to Bedrock)
+ MATCH path_target = (aws)--(target_role:AWSRole)-[:TRUSTS_AWS_PRINCIPAL]->(:AWSPrincipal {{arn: 'bedrock.amazonaws.com'}})
+ WHERE any(resource IN stmt_passrole.resource WHERE
+ resource = '*'
+ OR target_role.arn CONTAINS resource
+ OR resource CONTAINS target_role.name
+ )
+
+ UNWIND nodes(path_principal) + nodes(path_target) as n
+ OPTIONAL MATCH (n)-[pfr]-(pf:{PROWLER_FINDING_LABEL} {{status: 'FAIL', provider_uid: $provider_uid}})
+
+ RETURN path_principal, path_target,
+ collect(DISTINCT pf) as dpf, collect(DISTINCT pfr) as dpfr
+ """,
+ parameters=[],
+)
+
+# BEDROCK-002
+AWS_BEDROCK_PRIVESC_INVOKE_CODE_INTERPRETER = AttackPathsQueryDefinition(
+ id="aws-bedrock-privesc-invoke-code-interpreter",
+ name="Bedrock Code Interpreter Session Hijacking (BEDROCK-002)",
+ short_description="Start a session on an existing Bedrock code interpreter to exfiltrate its privileged role credentials.",
+ description="Detect principals who can start sessions and invoke code on existing Bedrock AgentCore code interpreters. This allows executing arbitrary Python code within an interpreter that has a privileged role attached, gaining that role's credentials via the MicroVM Metadata Service without requiring iam:PassRole.",
+ attribution=AttackPathsQueryAttribution(
+ text="pathfinding.cloud - BEDROCK-002 - bedrock-agentcore:StartCodeInterpreterSession + bedrock-agentcore:InvokeCodeInterpreter",
+ link="https://pathfinding.cloud/paths/bedrock-002",
+ ),
+ provider="aws",
+ cypher=f"""
+ // Find principals with bedrock-agentcore:StartCodeInterpreterSession permission
+ MATCH path_principal = (aws:AWSAccount {{id: $provider_uid}})--(principal:AWSPrincipal)--(session_policy:AWSPolicy)--(stmt_session:AWSPolicyStatement)
+ WHERE stmt_session.effect = 'Allow'
+ AND any(action IN stmt_session.action WHERE
+ toLower(action) = 'bedrock-agentcore:startcodeinterpretersession'
+ OR toLower(action) = 'bedrock-agentcore:*'
+ OR action = '*'
+ )
+
+ // Find bedrock-agentcore:InvokeCodeInterpreter permission
+ MATCH (principal)--(invoke_policy:AWSPolicy)--(stmt_invoke:AWSPolicyStatement)
+ WHERE stmt_invoke.effect = 'Allow'
+ AND any(action IN stmt_invoke.action WHERE
+ toLower(action) = 'bedrock-agentcore:invokecodeinterpreter'
+ OR toLower(action) = 'bedrock-agentcore:*'
+ OR action = '*'
+ )
+
+ // Find roles that trust Bedrock service (already attached to existing code interpreters)
+ MATCH path_target = (aws)--(target_role:AWSRole)-[:TRUSTS_AWS_PRINCIPAL]->(:AWSPrincipal {{arn: 'bedrock.amazonaws.com'}})
+
+ UNWIND nodes(path_principal) + nodes(path_target) as n
+ OPTIONAL MATCH (n)-[pfr]-(pf:{PROWLER_FINDING_LABEL} {{status: 'FAIL', provider_uid: $provider_uid}})
+
+ RETURN path_principal, path_target,
+ collect(DISTINCT pf) as dpf, collect(DISTINCT pfr) as dpfr
+ """,
+ parameters=[],
+)
+
+# CLOUDFORMATION-001
+AWS_CLOUDFORMATION_PRIVESC_PASSROLE_CREATE_STACK = AttackPathsQueryDefinition(
+ id="aws-cloudformation-privesc-passrole-create-stack",
+ name="CloudFormation Stack Creation with Privileged Role (CLOUDFORMATION-001)",
+ short_description="Create a CloudFormation stack with a privileged role to provision arbitrary AWS resources.",
+ description="Detect principals who can pass IAM roles and create CloudFormation stacks. This allows launching a stack with a malicious template that executes with the passed role's permissions, enabling creation of resources like IAM users, Lambda functions, or EC2 instances controlled by the attacker.",
+ attribution=AttackPathsQueryAttribution(
+ text="pathfinding.cloud - CLOUDFORMATION-001 - iam:PassRole + cloudformation:CreateStack",
+ link="https://pathfinding.cloud/paths/cloudformation-001",
+ ),
+ provider="aws",
+ cypher=f"""
+ // Find principals with iam:PassRole permission
+ MATCH path_principal = (aws:AWSAccount {{id: $provider_uid}})--(principal:AWSPrincipal)--(passrole_policy:AWSPolicy)--(stmt_passrole:AWSPolicyStatement)
+ WHERE stmt_passrole.effect = 'Allow'
+ AND any(action IN stmt_passrole.action WHERE
+ toLower(action) = 'iam:passrole'
+ OR toLower(action) = 'iam:*'
+ OR action = '*'
+ )
+
+ // Find cloudformation:CreateStack permission
+ MATCH (principal)--(cfn_policy:AWSPolicy)--(stmt_cfn:AWSPolicyStatement)
+ WHERE stmt_cfn.effect = 'Allow'
+ AND any(action IN stmt_cfn.action WHERE
+ toLower(action) = 'cloudformation:createstack'
+ OR toLower(action) = 'cloudformation:*'
+ OR action = '*'
+ )
+
+ // Find roles that trust CloudFormation service (can be passed to CloudFormation)
+ MATCH path_target = (aws)--(target_role:AWSRole)-[:TRUSTS_AWS_PRINCIPAL]->(:AWSPrincipal {{arn: 'cloudformation.amazonaws.com'}})
+ WHERE any(resource IN stmt_passrole.resource WHERE
+ resource = '*'
+ OR target_role.arn CONTAINS resource
+ OR resource CONTAINS target_role.name
+ )
+
+ UNWIND nodes(path_principal) + nodes(path_target) as n
+ OPTIONAL MATCH (n)-[pfr]-(pf:{PROWLER_FINDING_LABEL} {{status: 'FAIL', provider_uid: $provider_uid}})
+
+ RETURN path_principal, path_target,
+ collect(DISTINCT pf) as dpf, collect(DISTINCT pfr) as dpfr
+ """,
+ parameters=[],
+)
+
+# CLOUDFORMATION-002
+AWS_CLOUDFORMATION_PRIVESC_UPDATE_STACK = AttackPathsQueryDefinition(
+ id="aws-cloudformation-privesc-update-stack",
+ name="CloudFormation Stack Update for Role Access (CLOUDFORMATION-002)",
+ short_description="Update an existing CloudFormation stack to leverage its already-attached privileged service role.",
+ description="Detect principals who can update existing CloudFormation stacks. This allows modifying a stack's template to add new resources (such as IAM roles with admin access) that are created with the stack's already-attached service role permissions, without requiring iam:PassRole.",
+ attribution=AttackPathsQueryAttribution(
+ text="pathfinding.cloud - CLOUDFORMATION-002 - cloudformation:UpdateStack",
+ link="https://pathfinding.cloud/paths/cloudformation-002",
+ ),
+ provider="aws",
+ cypher=f"""
+ // Find principals with cloudformation:UpdateStack permission
+ MATCH path_principal = (aws:AWSAccount {{id: $provider_uid}})--(principal:AWSPrincipal)--(update_policy:AWSPolicy)--(stmt_update:AWSPolicyStatement)
+ WHERE stmt_update.effect = 'Allow'
+ AND any(action IN stmt_update.action WHERE
+ toLower(action) = 'cloudformation:updatestack'
+ OR toLower(action) = 'cloudformation:*'
+ OR action = '*'
+ )
+
+ // Find roles that trust CloudFormation service (already attached to existing stacks)
+ MATCH path_target = (aws)--(target_role:AWSRole)-[:TRUSTS_AWS_PRINCIPAL]->(:AWSPrincipal {{arn: 'cloudformation.amazonaws.com'}})
+
+ UNWIND nodes(path_principal) + nodes(path_target) as n
+ OPTIONAL MATCH (n)-[pfr]-(pf:{PROWLER_FINDING_LABEL} {{status: 'FAIL', provider_uid: $provider_uid}})
+
+ RETURN path_principal, path_target,
+ collect(DISTINCT pf) as dpf, collect(DISTINCT pfr) as dpfr
+ """,
+ parameters=[],
+)
+
+# CLOUDFORMATION-003
+AWS_CLOUDFORMATION_PRIVESC_PASSROLE_CREATE_STACKSET = AttackPathsQueryDefinition(
+ id="aws-cloudformation-privesc-passrole-create-stackset",
+ name="CloudFormation StackSet Creation with Privileged Role (CLOUDFORMATION-003)",
+ short_description="Create a CloudFormation StackSet with a privileged execution role to provision arbitrary resources across accounts.",
+ description="Detect principals who can pass IAM roles, create CloudFormation StackSets, and deploy stack instances. This allows creating a StackSet with a malicious template and a privileged execution role, then deploying instances that create resources (such as IAM roles with admin access) using that role's permissions.",
+ attribution=AttackPathsQueryAttribution(
+ text="pathfinding.cloud - CLOUDFORMATION-003 - iam:PassRole + cloudformation:CreateStackSet + cloudformation:CreateStackInstances",
+ link="https://pathfinding.cloud/paths/cloudformation-003",
+ ),
+ provider="aws",
+ cypher=f"""
+ // Find principals with iam:PassRole permission
+ MATCH path_principal = (aws:AWSAccount {{id: $provider_uid}})--(principal:AWSPrincipal)--(passrole_policy:AWSPolicy)--(stmt_passrole:AWSPolicyStatement)
+ WHERE stmt_passrole.effect = 'Allow'
+ AND any(action IN stmt_passrole.action WHERE
+ toLower(action) = 'iam:passrole'
+ OR toLower(action) = 'iam:*'
+ OR action = '*'
+ )
+
+ // Find cloudformation:CreateStackSet permission
+ MATCH (principal)--(cfn_policy:AWSPolicy)--(stmt_cfn:AWSPolicyStatement)
+ WHERE stmt_cfn.effect = 'Allow'
+ AND any(action IN stmt_cfn.action WHERE
+ toLower(action) = 'cloudformation:createstackset'
+ OR toLower(action) = 'cloudformation:*'
+ OR action = '*'
+ )
+
+ // Find cloudformation:CreateStackInstances permission
+ MATCH (principal)--(cfn_instances_policy:AWSPolicy)--(stmt_cfn_instances:AWSPolicyStatement)
+ WHERE stmt_cfn_instances.effect = 'Allow'
+ AND any(action IN stmt_cfn_instances.action WHERE
+ toLower(action) = 'cloudformation:createstackinstances'
+ OR toLower(action) = 'cloudformation:*'
+ OR action = '*'
+ )
+
+ // Find roles that trust CloudFormation service (can be passed as execution role)
+ MATCH path_target = (aws)--(target_role:AWSRole)-[:TRUSTS_AWS_PRINCIPAL]->(:AWSPrincipal {{arn: 'cloudformation.amazonaws.com'}})
+ WHERE any(resource IN stmt_passrole.resource WHERE
+ resource = '*'
+ OR target_role.arn CONTAINS resource
+ OR resource CONTAINS target_role.name
+ )
+
+ UNWIND nodes(path_principal) + nodes(path_target) as n
+ OPTIONAL MATCH (n)-[pfr]-(pf:{PROWLER_FINDING_LABEL} {{status: 'FAIL', provider_uid: $provider_uid}})
+
+ RETURN path_principal, path_target,
+ collect(DISTINCT pf) as dpf, collect(DISTINCT pfr) as dpfr
+ """,
+ parameters=[],
+)
+
+# CLOUDFORMATION-004
+AWS_CLOUDFORMATION_PRIVESC_PASSROLE_UPDATE_STACKSET = AttackPathsQueryDefinition(
+ id="aws-cloudformation-privesc-passrole-update-stackset",
+ name="CloudFormation StackSet Update with Privileged Role (CLOUDFORMATION-004)",
+ short_description="Update an existing CloudFormation StackSet to inject malicious resources using a privileged execution role.",
+ description="Detect principals who can pass IAM roles and update CloudFormation StackSets. This allows modifying an existing StackSet's template to add resources (such as IAM roles with admin access) that are provisioned by the StackSet's privileged execution role across target accounts.",
+ attribution=AttackPathsQueryAttribution(
+ text="pathfinding.cloud - CLOUDFORMATION-004 - iam:PassRole + cloudformation:UpdateStackSet",
+ link="https://pathfinding.cloud/paths/cloudformation-004",
+ ),
+ provider="aws",
+ cypher=f"""
+ // Find principals with iam:PassRole permission
+ MATCH path_principal = (aws:AWSAccount {{id: $provider_uid}})--(principal:AWSPrincipal)--(passrole_policy:AWSPolicy)--(stmt_passrole:AWSPolicyStatement)
+ WHERE stmt_passrole.effect = 'Allow'
+ AND any(action IN stmt_passrole.action WHERE
+ toLower(action) = 'iam:passrole'
+ OR toLower(action) = 'iam:*'
+ OR action = '*'
+ )
+
+ // Find cloudformation:UpdateStackSet permission
+ MATCH (principal)--(cfn_policy:AWSPolicy)--(stmt_cfn:AWSPolicyStatement)
+ WHERE stmt_cfn.effect = 'Allow'
+ AND any(action IN stmt_cfn.action WHERE
+ toLower(action) = 'cloudformation:updatestackset'
+ OR toLower(action) = 'cloudformation:*'
+ OR action = '*'
+ )
+
+ // Find roles that trust CloudFormation service (can be passed as execution role)
+ MATCH path_target = (aws)--(target_role:AWSRole)-[:TRUSTS_AWS_PRINCIPAL]->(:AWSPrincipal {{arn: 'cloudformation.amazonaws.com'}})
+ WHERE any(resource IN stmt_passrole.resource WHERE
+ resource = '*'
+ OR target_role.arn CONTAINS resource
+ OR resource CONTAINS target_role.name
+ )
+
+ UNWIND nodes(path_principal) + nodes(path_target) as n
+ OPTIONAL MATCH (n)-[pfr]-(pf:{PROWLER_FINDING_LABEL} {{status: 'FAIL', provider_uid: $provider_uid}})
+
+ RETURN path_principal, path_target,
+ collect(DISTINCT pf) as dpf, collect(DISTINCT pfr) as dpfr
+ """,
+ parameters=[],
+)
+
+# CLOUDFORMATION-005
+AWS_CLOUDFORMATION_PRIVESC_CHANGESET = AttackPathsQueryDefinition(
+ id="aws-cloudformation-privesc-changeset",
+ name="CloudFormation Change Set Privilege Escalation (CLOUDFORMATION-005)",
+ short_description="Create and execute a change set on an existing stack to leverage its privileged service role.",
+ description="Detect principals who can create and execute CloudFormation change sets. This allows modifying an existing stack's template through a staged change set, inheriting the stack's already-attached service role permissions to provision arbitrary resources without requiring iam:PassRole.",
+ attribution=AttackPathsQueryAttribution(
+ text="pathfinding.cloud - CLOUDFORMATION-005 - cloudformation:CreateChangeSet + cloudformation:ExecuteChangeSet",
+ link="https://pathfinding.cloud/paths/cloudformation-005",
+ ),
+ provider="aws",
+ cypher=f"""
+ // Find principals with cloudformation:CreateChangeSet permission
+ MATCH path_principal = (aws:AWSAccount {{id: $provider_uid}})--(principal:AWSPrincipal)--(create_policy:AWSPolicy)--(stmt_create:AWSPolicyStatement)
+ WHERE stmt_create.effect = 'Allow'
+ AND any(action IN stmt_create.action WHERE
+ toLower(action) = 'cloudformation:createchangeset'
+ OR toLower(action) = 'cloudformation:*'
+ OR action = '*'
+ )
+
+ // Find cloudformation:ExecuteChangeSet permission
+ MATCH (principal)--(exec_policy:AWSPolicy)--(stmt_exec:AWSPolicyStatement)
+ WHERE stmt_exec.effect = 'Allow'
+ AND any(action IN stmt_exec.action WHERE
+ toLower(action) = 'cloudformation:executechangeset'
+ OR toLower(action) = 'cloudformation:*'
+ OR action = '*'
+ )
+
+ // Find roles that trust CloudFormation service (already attached to existing stacks)
+ MATCH path_target = (aws)--(target_role:AWSRole)-[:TRUSTS_AWS_PRINCIPAL]->(:AWSPrincipal {{arn: 'cloudformation.amazonaws.com'}})
+
+ UNWIND nodes(path_principal) + nodes(path_target) as n
+ OPTIONAL MATCH (n)-[pfr]-(pf:{PROWLER_FINDING_LABEL} {{status: 'FAIL', provider_uid: $provider_uid}})
+
+ RETURN path_principal, path_target,
+ collect(DISTINCT pf) as dpf, collect(DISTINCT pfr) as dpfr
+ """,
+ parameters=[],
+)
+
+# CODEBUILD-001
+AWS_CODEBUILD_PRIVESC_PASSROLE_CREATE_PROJECT = AttackPathsQueryDefinition(
+ id="aws-codebuild-privesc-passrole-create-project",
+ name="CodeBuild Project Creation with Privileged Role (CODEBUILD-001)",
+ short_description="Create a CodeBuild project with a privileged role to execute arbitrary code via a malicious buildspec.",
+ description="Detect principals who can pass IAM roles, create CodeBuild projects, and start builds. This allows creating a project with a privileged role attached and executing arbitrary code through a malicious buildspec, gaining that role's permissions.",
+ attribution=AttackPathsQueryAttribution(
+ text="pathfinding.cloud - CODEBUILD-001 - iam:PassRole + codebuild:CreateProject + codebuild:StartBuild",
+ link="https://pathfinding.cloud/paths/codebuild-001",
+ ),
+ provider="aws",
+ cypher=f"""
+ // Find principals with iam:PassRole permission
+ MATCH path_principal = (aws:AWSAccount {{id: $provider_uid}})--(principal:AWSPrincipal)--(passrole_policy:AWSPolicy)--(stmt_passrole:AWSPolicyStatement)
+ WHERE stmt_passrole.effect = 'Allow'
+ AND any(action IN stmt_passrole.action WHERE
+ toLower(action) = 'iam:passrole'
+ OR toLower(action) = 'iam:*'
+ OR action = '*'
+ )
+
+ // Find codebuild:CreateProject permission
+ MATCH (principal)--(create_policy:AWSPolicy)--(stmt_create:AWSPolicyStatement)
+ WHERE stmt_create.effect = 'Allow'
+ AND any(action IN stmt_create.action WHERE
+ toLower(action) = 'codebuild:createproject'
+ OR toLower(action) = 'codebuild:*'
+ OR action = '*'
+ )
+
+ // Find codebuild:StartBuild permission
+ MATCH (principal)--(build_policy:AWSPolicy)--(stmt_build:AWSPolicyStatement)
+ WHERE stmt_build.effect = 'Allow'
+ AND any(action IN stmt_build.action WHERE
+ toLower(action) = 'codebuild:startbuild'
+ OR toLower(action) = 'codebuild:*'
+ OR action = '*'
+ )
+
+ // Find roles that trust CodeBuild service (can be passed to CodeBuild)
+ MATCH path_target = (aws)--(target_role:AWSRole)-[:TRUSTS_AWS_PRINCIPAL]->(:AWSPrincipal {{arn: 'codebuild.amazonaws.com'}})
+ WHERE any(resource IN stmt_passrole.resource WHERE
+ resource = '*'
+ OR target_role.arn CONTAINS resource
+ OR resource CONTAINS target_role.name
+ )
+
+ UNWIND nodes(path_principal) + nodes(path_target) as n
+ OPTIONAL MATCH (n)-[pfr]-(pf:{PROWLER_FINDING_LABEL} {{status: 'FAIL', provider_uid: $provider_uid}})
+
+ RETURN path_principal, path_target,
+ collect(DISTINCT pf) as dpf, collect(DISTINCT pfr) as dpfr
+ """,
+ parameters=[],
+)
+
+# CODEBUILD-002
+AWS_CODEBUILD_PRIVESC_START_BUILD = AttackPathsQueryDefinition(
+ id="aws-codebuild-privesc-start-build",
+ name="CodeBuild Buildspec Override for Role Access (CODEBUILD-002)",
+ short_description="Start a build on an existing CodeBuild project with a buildspec override to execute code with its privileged role.",
+ description="Detect principals who can start builds on existing CodeBuild projects. This allows overriding the buildspec with malicious commands that execute with the project's already-attached service role permissions, without requiring iam:PassRole or codebuild:CreateProject.",
+ attribution=AttackPathsQueryAttribution(
+ text="pathfinding.cloud - CODEBUILD-002 - codebuild:StartBuild",
+ link="https://pathfinding.cloud/paths/codebuild-002",
+ ),
+ provider="aws",
+ cypher=f"""
+ // Find principals with codebuild:StartBuild permission
+ MATCH path_principal = (aws:AWSAccount {{id: $provider_uid}})--(principal:AWSPrincipal)--(build_policy:AWSPolicy)--(stmt_build:AWSPolicyStatement)
+ WHERE stmt_build.effect = 'Allow'
+ AND any(action IN stmt_build.action WHERE
+ toLower(action) = 'codebuild:startbuild'
+ OR toLower(action) = 'codebuild:*'
+ OR action = '*'
+ )
+
+ // Find roles that trust CodeBuild service (already attached to existing projects)
+ MATCH path_target = (aws)--(target_role:AWSRole)-[:TRUSTS_AWS_PRINCIPAL]->(:AWSPrincipal {{arn: 'codebuild.amazonaws.com'}})
+
+ UNWIND nodes(path_principal) + nodes(path_target) as n
+ OPTIONAL MATCH (n)-[pfr]-(pf:{PROWLER_FINDING_LABEL} {{status: 'FAIL', provider_uid: $provider_uid}})
+
+ RETURN path_principal, path_target,
+ collect(DISTINCT pf) as dpf, collect(DISTINCT pfr) as dpfr
+ """,
+ parameters=[],
+)
+
+# CODEBUILD-003
+AWS_CODEBUILD_PRIVESC_START_BUILD_BATCH = AttackPathsQueryDefinition(
+ id="aws-codebuild-privesc-start-build-batch",
+ name="CodeBuild Batch Buildspec Override for Role Access (CODEBUILD-003)",
+ short_description="Start a batch build on an existing CodeBuild project with a buildspec override to execute code with its privileged role.",
+ description="Detect principals who can start batch builds on existing CodeBuild projects. This allows overriding the buildspec with malicious commands that execute with the project's already-attached service role permissions, without requiring iam:PassRole or codebuild:CreateProject.",
+ attribution=AttackPathsQueryAttribution(
+ text="pathfinding.cloud - CODEBUILD-003 - codebuild:StartBuildBatch",
+ link="https://pathfinding.cloud/paths/codebuild-003",
+ ),
+ provider="aws",
+ cypher=f"""
+ // Find principals with codebuild:StartBuildBatch permission
+ MATCH path_principal = (aws:AWSAccount {{id: $provider_uid}})--(principal:AWSPrincipal)--(build_policy:AWSPolicy)--(stmt_build:AWSPolicyStatement)
+ WHERE stmt_build.effect = 'Allow'
+ AND any(action IN stmt_build.action WHERE
+ toLower(action) = 'codebuild:startbuildbatch'
+ OR toLower(action) = 'codebuild:*'
+ OR action = '*'
+ )
+
+ // Find roles that trust CodeBuild service (already attached to existing projects)
+ MATCH path_target = (aws)--(target_role:AWSRole)-[:TRUSTS_AWS_PRINCIPAL]->(:AWSPrincipal {{arn: 'codebuild.amazonaws.com'}})
+
+ UNWIND nodes(path_principal) + nodes(path_target) as n
+ OPTIONAL MATCH (n)-[pfr]-(pf:{PROWLER_FINDING_LABEL} {{status: 'FAIL', provider_uid: $provider_uid}})
+
+ RETURN path_principal, path_target,
+ collect(DISTINCT pf) as dpf, collect(DISTINCT pfr) as dpfr
+ """,
+ parameters=[],
+)
+
+# CODEBUILD-004
+AWS_CODEBUILD_PRIVESC_PASSROLE_CREATE_PROJECT_BATCH = AttackPathsQueryDefinition(
+ id="aws-codebuild-privesc-passrole-create-project-batch",
+ name="CodeBuild Batch Project Creation with Privileged Role (CODEBUILD-004)",
+ short_description="Create a CodeBuild project configured for batch builds with a privileged role to execute arbitrary code via a malicious buildspec.",
+ description="Detect principals who can pass IAM roles, create CodeBuild projects, and start batch builds. This allows creating a project with a privileged role attached and executing arbitrary code through a malicious batch buildspec, gaining that role's permissions.",
+ attribution=AttackPathsQueryAttribution(
+ text="pathfinding.cloud - CODEBUILD-004 - iam:PassRole + codebuild:CreateProject + codebuild:StartBuildBatch",
+ link="https://pathfinding.cloud/paths/codebuild-004",
+ ),
+ provider="aws",
+ cypher=f"""
+ // Find principals with iam:PassRole permission
+ MATCH path_principal = (aws:AWSAccount {{id: $provider_uid}})--(principal:AWSPrincipal)--(passrole_policy:AWSPolicy)--(stmt_passrole:AWSPolicyStatement)
+ WHERE stmt_passrole.effect = 'Allow'
+ AND any(action IN stmt_passrole.action WHERE
+ toLower(action) = 'iam:passrole'
+ OR toLower(action) = 'iam:*'
+ OR action = '*'
+ )
+
+ // Find codebuild:CreateProject permission
+ MATCH (principal)--(create_policy:AWSPolicy)--(stmt_create:AWSPolicyStatement)
+ WHERE stmt_create.effect = 'Allow'
+ AND any(action IN stmt_create.action WHERE
+ toLower(action) = 'codebuild:createproject'
+ OR toLower(action) = 'codebuild:*'
+ OR action = '*'
+ )
+
+ // Find codebuild:StartBuildBatch permission
+ MATCH (principal)--(batch_policy:AWSPolicy)--(stmt_batch:AWSPolicyStatement)
+ WHERE stmt_batch.effect = 'Allow'
+ AND any(action IN stmt_batch.action WHERE
+ toLower(action) = 'codebuild:startbuildbatch'
+ OR toLower(action) = 'codebuild:*'
+ OR action = '*'
+ )
+
+ // Find roles that trust CodeBuild service (can be passed to CodeBuild)
+ MATCH path_target = (aws)--(target_role:AWSRole)-[:TRUSTS_AWS_PRINCIPAL]->(:AWSPrincipal {{arn: 'codebuild.amazonaws.com'}})
+ WHERE any(resource IN stmt_passrole.resource WHERE
+ resource = '*'
+ OR target_role.arn CONTAINS resource
+ OR resource CONTAINS target_role.name
+ )
+
+ UNWIND nodes(path_principal) + nodes(path_target) as n
+ OPTIONAL MATCH (n)-[pfr]-(pf:{PROWLER_FINDING_LABEL} {{status: 'FAIL', provider_uid: $provider_uid}})
+
+ RETURN path_principal, path_target,
+ collect(DISTINCT pf) as dpf, collect(DISTINCT pfr) as dpfr
+ """,
+ parameters=[],
+)
+
+# DATAPIPELINE-001
+AWS_DATAPIPELINE_PRIVESC_PASSROLE_CREATE_PIPELINE = AttackPathsQueryDefinition(
+ id="aws-datapipeline-privesc-passrole-create-pipeline",
+ name="Data Pipeline Creation with Privileged Role (DATAPIPELINE-001)",
+ short_description="Create a Data Pipeline with a privileged role to execute arbitrary commands on provisioned infrastructure.",
+ description="Detect principals who can pass IAM roles, create Data Pipelines, define pipeline objects, and activate them. This allows creating a pipeline with a privileged role attached and executing arbitrary commands on the provisioned EC2 instances or EMR clusters, gaining that role's permissions.",
+ attribution=AttackPathsQueryAttribution(
+ text="pathfinding.cloud - DATAPIPELINE-001 - iam:PassRole + datapipeline:CreatePipeline + datapipeline:PutPipelineDefinition + datapipeline:ActivatePipeline",
+ link="https://pathfinding.cloud/paths/datapipeline-001",
+ ),
+ provider="aws",
+ cypher=f"""
+ // Find principals with iam:PassRole permission
+ MATCH path_principal = (aws:AWSAccount {{id: $provider_uid}})--(principal:AWSPrincipal)--(passrole_policy:AWSPolicy)--(stmt_passrole:AWSPolicyStatement)
+ WHERE stmt_passrole.effect = 'Allow'
+ AND any(action IN stmt_passrole.action WHERE
+ toLower(action) = 'iam:passrole'
+ OR toLower(action) = 'iam:*'
+ OR action = '*'
+ )
+
+ // Find datapipeline:CreatePipeline permission
+ MATCH (principal)--(create_policy:AWSPolicy)--(stmt_create:AWSPolicyStatement)
+ WHERE stmt_create.effect = 'Allow'
+ AND any(action IN stmt_create.action WHERE
+ toLower(action) = 'datapipeline:createpipeline'
+ OR toLower(action) = 'datapipeline:*'
+ OR action = '*'
+ )
+
+ // Find datapipeline:PutPipelineDefinition permission
+ MATCH (principal)--(put_policy:AWSPolicy)--(stmt_put:AWSPolicyStatement)
+ WHERE stmt_put.effect = 'Allow'
+ AND any(action IN stmt_put.action WHERE
+ toLower(action) = 'datapipeline:putpipelinedefinition'
+ OR toLower(action) = 'datapipeline:*'
+ OR action = '*'
+ )
+
+ // Find datapipeline:ActivatePipeline permission
+ MATCH (principal)--(activate_policy:AWSPolicy)--(stmt_activate:AWSPolicyStatement)
+ WHERE stmt_activate.effect = 'Allow'
+ AND any(action IN stmt_activate.action WHERE
+ toLower(action) = 'datapipeline:activatepipeline'
+ OR toLower(action) = 'datapipeline:*'
+ OR action = '*'
+ )
+
+ // Find roles that trust Data Pipeline or EMR service (can be passed to DataPipeline)
+ MATCH path_target = (aws)--(target_role:AWSRole)-[:TRUSTS_AWS_PRINCIPAL]->(trusted_principal:AWSPrincipal)
+ WHERE trusted_principal.arn IN ['datapipeline.amazonaws.com', 'elasticmapreduce.amazonaws.com']
+ AND any(resource IN stmt_passrole.resource WHERE
+ resource = '*'
+ OR target_role.arn CONTAINS resource
+ OR resource CONTAINS target_role.name
+ )
+
+ UNWIND nodes(path_principal) + nodes(path_target) as n
+ OPTIONAL MATCH (n)-[pfr]-(pf:{PROWLER_FINDING_LABEL} {{status: 'FAIL', provider_uid: $provider_uid}})
+
+ RETURN path_principal, path_target,
+ collect(DISTINCT pf) as dpf, collect(DISTINCT pfr) as dpfr
+ """,
+ parameters=[],
+)
+
+# EC2-001
+AWS_EC2_PRIVESC_PASSROLE_IAM = AttackPathsQueryDefinition(
+ id="aws-ec2-privesc-passrole-iam",
+ name="EC2 Instance Launch with Privileged Role (EC2-001)",
+ short_description="Launch EC2 instances with privileged IAM roles to gain their permissions via IMDS.",
+ description="Detect principals who can launch EC2 instances with privileged IAM roles attached. This allows gaining the permissions of the passed role by accessing the EC2 instance metadata service.",
+ attribution=AttackPathsQueryAttribution(
+ text="pathfinding.cloud - EC2-001 - iam:PassRole + ec2:RunInstances",
+ link="https://pathfinding.cloud/paths/ec2-001",
+ ),
+ provider="aws",
+ cypher=f"""
+ // Find principals with iam:PassRole permission
+ MATCH path_principal = (aws:AWSAccount {{id: $provider_uid}})--(principal:AWSPrincipal)--(passrole_policy:AWSPolicy)--(stmt_passrole:AWSPolicyStatement)
+ WHERE stmt_passrole.effect = 'Allow'
+ AND any(action IN stmt_passrole.action WHERE
+ toLower(action) = 'iam:passrole'
+ OR toLower(action) = 'iam:*'
+ OR action = '*'
+ )
+
+ // Find ec2:RunInstances permission
+ MATCH (principal)--(ec2_policy:AWSPolicy)--(stmt_ec2:AWSPolicyStatement)
WHERE stmt_ec2.effect = 'Allow'
AND any(action IN stmt_ec2.action WHERE
toLower(action) = 'ec2:runinstances'
@@ -369,309 +1011,2369 @@ AWS_IAM_PRIVESC_PASSROLE_EC2 = AttackPathsQueryDefinition(
)
// Find roles that trust EC2 service (can be passed to EC2)
- MATCH path_target = (aws)--(target_role:AWSRole)
- WHERE target_role.arn CONTAINS $provider_uid
- // Check if principal can pass this role
- AND any(resource IN stmt_passrole.resource WHERE
- resource = '*'
- OR target_role.arn CONTAINS resource
- OR resource CONTAINS target_role.name
- )
+ MATCH path_target = (aws)--(target_role:AWSRole)-[:TRUSTS_AWS_PRINCIPAL]->(:AWSPrincipal {{arn: 'ec2.amazonaws.com'}})
+ WHERE any(resource IN stmt_passrole.resource WHERE
+ resource = '*'
+ OR target_role.arn CONTAINS resource
+ OR resource CONTAINS target_role.name
+ )
- // Check if target role has elevated permissions (optional, for severity assessment)
- OPTIONAL MATCH (target_role)--(role_policy:AWSPolicy)--(role_stmt:AWSPolicyStatement)
- WHERE role_stmt.effect = 'Allow'
- AND (
- any(action IN role_stmt.action WHERE action = '*')
- OR any(action IN role_stmt.action WHERE toLower(action) = 'iam:*')
- )
-
- CALL apoc.create.vRelationship(principal, 'CAN_LAUNCH', {{
- via: 'ec2:RunInstances + iam:PassRole'
- }}, ec2_node)
- YIELD rel AS launch_rel
-
- CALL apoc.create.vRelationship(ec2_node, 'ASSUMES_ROLE', {{}}, target_role)
- YIELD rel AS assumes_rel
-
- CALL apoc.create.vRelationship(target_role, 'GRANTS_ACCESS', {{
- reference: 'https://pathfinding.cloud/paths/ec2-001'
- }}, escalation_outcome)
- YIELD rel AS grants_rel
-
- UNWIND nodes(path_principal) + nodes(path_passrole) + nodes(path_ec2) + nodes(path_target) as n
- OPTIONAL MATCH (n)-[pfr]-(pf:{PROWLER_FINDING_LABEL})
- WHERE pf.status = 'FAIL'
-
- RETURN path_principal, path_passrole, path_ec2, path_target,
- ec2_node, escalation_outcome, launch_rel, assumes_rel, grants_rel,
- collect(DISTINCT pf) as dpf, collect(DISTINCT pfr) as dpfr
- """,
- parameters=[],
-)
-
-# TODO: Add ProwlerFinding nodes
-AWS_GLUE_PRIVESC_PASSROLE_DEV_ENDPOINT = AttackPathsQueryDefinition(
- id="aws-glue-privesc-passrole-dev-endpoint",
- name="Privilege Escalation: Glue Dev Endpoint with PassRole",
- description="Detect principals that can escalate privileges by passing a role to a Glue development endpoint. The attacker creates a dev endpoint with an arbitrary role attached, then accesses those credentials through the endpoint.",
- provider="aws",
- cypher="""
- CALL apoc.create.vNode(['PrivilegeEscalation'], {
- id: 'effective-administrator-glue',
- check_title: 'Privilege Escalation',
- name: 'Effective Administrator (Glue)',
- status: 'FAIL',
- severity: 'critical'
- })
- YIELD node AS escalation_outcome
-
- WITH escalation_outcome
-
- // Find principals in the account
- MATCH path_principal = (aws:AWSAccount {id: $provider_uid})--(principal:AWSPrincipal)
-
- // Principal can assume roles (up to 2 hops)
- OPTIONAL MATCH path_assume = (principal)-[:STS_ASSUMEROLE_ALLOW*0..2]->(acting_as:AWSRole)
- WITH escalation_outcome, principal, path_principal, path_assume,
- CASE WHEN path_assume IS NULL THEN principal ELSE acting_as END AS effective_principal
-
- // Find iam:PassRole permission
- MATCH path_passrole = (effective_principal)--(passrole_policy:AWSPolicy)--(passrole_stmt:AWSPolicyStatement)
- WHERE passrole_stmt.effect = 'Allow'
- AND any(action IN passrole_stmt.action WHERE toLower(action) = 'iam:passrole' OR action = '*')
-
- // Find Glue CreateDevEndpoint permission
- MATCH (effective_principal)--(glue_policy:AWSPolicy)--(glue_stmt:AWSPolicyStatement)
- WHERE glue_stmt.effect = 'Allow'
- AND any(action IN glue_stmt.action WHERE toLower(action) = 'glue:createdevendpoint' OR action = '*' OR toLower(action) = 'glue:*')
-
- // Find target role with elevated permissions
- MATCH (aws)--(target_role:AWSRole)--(target_policy:AWSPolicy)--(target_stmt:AWSPolicyStatement)
- WHERE target_stmt.effect = 'Allow'
- AND (
- any(action IN target_stmt.action WHERE action = '*')
- OR any(action IN target_stmt.action WHERE toLower(action) = 'iam:*')
- )
-
- // Deduplicate before creating virtual nodes
- WITH DISTINCT escalation_outcome, aws, principal, effective_principal, target_role
-
- // Create virtual Glue endpoint node (one per unique principal->target pair)
- CALL apoc.create.vNode(['GlueDevEndpoint'], {
- name: 'New Dev Endpoint',
- description: 'Glue endpoint with target role attached',
- id: effective_principal.arn + '->' + target_role.arn
- })
- YIELD node AS glue_endpoint
-
- CALL apoc.create.vRelationship(effective_principal, 'CREATES_ENDPOINT', {
- permissions: ['iam:PassRole', 'glue:CreateDevEndpoint'],
- technique: 'new-passrole'
- }, glue_endpoint)
- YIELD rel AS create_rel
-
- CALL apoc.create.vRelationship(glue_endpoint, 'RUNS_AS', {}, target_role)
- YIELD rel AS runs_rel
-
- CALL apoc.create.vRelationship(target_role, 'GRANTS_ACCESS', {
- reference: 'https://pathfinding.cloud/paths/glue-001'
- }, escalation_outcome)
- YIELD rel AS grants_rel
-
- // Re-match paths for visualization
- MATCH path_principal = (aws)--(principal)
- MATCH path_target = (aws)--(target_role)
+ UNWIND nodes(path_principal) + nodes(path_target) as n
+ OPTIONAL MATCH (n)-[pfr]-(pf:{PROWLER_FINDING_LABEL} {{status: 'FAIL', provider_uid: $provider_uid}})
RETURN path_principal, path_target,
- glue_endpoint, escalation_outcome, create_rel, runs_rel, grants_rel
+ collect(DISTINCT pf) as dpf, collect(DISTINCT pfr) as dpfr
""",
parameters=[],
)
-AWS_IAM_PRIVESC_ATTACH_ROLE_POLICY_ASSUME_ROLE = AttackPathsQueryDefinition(
- id="aws-iam-privesc-attach-role-policy-assume-role",
- name="Privilege Escalation: iam:AttachRolePolicy + sts:AssumeRole",
- description="Detect principals who can both attach policies to roles AND assume those roles. This two-step attack allows modifying a role's permissions then assuming it to gain elevated access. This is a principal-access escalation path (pathfinding.cloud: iam-014).",
+# EC2-002
+AWS_EC2_PRIVESC_MODIFY_INSTANCE_ATTRIBUTE = AttackPathsQueryDefinition(
+ id="aws-ec2-privesc-modify-instance-attribute",
+ name="EC2 Role Hijacking via UserData Injection (EC2-002)",
+ short_description="Inject malicious scripts into EC2 instance userData to gain the attached role's permissions.",
+ description="Detect principals who can modify EC2 instance userData, stop, and start instances. This allows injecting malicious scripts that execute on instance restart, gaining the permissions of the instance's attached IAM role.",
+ attribution=AttackPathsQueryAttribution(
+ text="pathfinding.cloud - EC2-002 - ec2:ModifyInstanceAttribute + ec2:StopInstances + ec2:StartInstances",
+ link="https://pathfinding.cloud/paths/ec2-002",
+ ),
provider="aws",
cypher=f"""
- // Create a virtual escalation outcome node (styled like a finding)
- CALL apoc.create.vNode(['PrivilegeEscalation'], {{
- id: 'effective-administrator',
- check_title: 'Privilege Escalation',
- name: 'Effective Administrator',
- status: 'FAIL',
- severity: 'critical'
- }})
- YIELD node AS admin_outcome
+ // Find principals with ec2:ModifyInstanceAttribute permission
+ MATCH path_principal = (aws:AWSAccount {{id: $provider_uid}})--(principal:AWSPrincipal)--(modify_policy:AWSPolicy)--(stmt_modify:AWSPolicyStatement)
+ WHERE stmt_modify.effect = 'Allow'
+ AND any(action IN stmt_modify.action WHERE
+ toLower(action) = 'ec2:modifyinstanceattribute'
+ OR toLower(action) = 'ec2:*'
+ OR action = '*'
+ )
- WITH admin_outcome
+ // Find ec2:StopInstances permission (can be same or different policy)
+ MATCH (principal)--(stop_policy:AWSPolicy)--(stmt_stop:AWSPolicyStatement)
+ WHERE stmt_stop.effect = 'Allow'
+ AND any(action IN stmt_stop.action WHERE
+ toLower(action) = 'ec2:stopinstances'
+ OR toLower(action) = 'ec2:*'
+ OR action = '*'
+ )
- // Find principals in the account
- MATCH path_principal = (aws:AWSAccount {{id: $provider_uid}})--(principal:AWSPrincipal)
+ // Find ec2:StartInstances permission (can be same or different policy)
+ MATCH (principal)--(start_policy:AWSPolicy)--(stmt_start:AWSPolicyStatement)
+ WHERE stmt_start.effect = 'Allow'
+ AND any(action IN stmt_start.action WHERE
+ toLower(action) = 'ec2:startinstances'
+ OR toLower(action) = 'ec2:*'
+ OR action = '*'
+ )
- // Find statements granting iam:AttachRolePolicy
- MATCH path_attach = (principal)--(attach_policy:AWSPolicy)--(stmt_attach:AWSPolicyStatement)
- WHERE stmt_attach.effect = 'Allow'
- AND any(action IN stmt_attach.action WHERE
+ // Find EC2 instances with instance profiles (potential targets)
+ MATCH path_target = (aws)--(ec2:EC2Instance)-[:STS_ASSUMEROLE_ALLOW]->(target_role:AWSRole)
+
+ UNWIND nodes(path_principal) + nodes(path_target) as n
+ OPTIONAL MATCH (n)-[pfr]-(pf:{PROWLER_FINDING_LABEL} {{status: 'FAIL', provider_uid: $provider_uid}})
+
+ RETURN path_principal, path_target,
+ collect(DISTINCT pf) as dpf, collect(DISTINCT pfr) as dpfr
+ """,
+ parameters=[],
+)
+
+# EC2-003
+AWS_EC2_PRIVESC_PASSROLE_SPOT_INSTANCES = AttackPathsQueryDefinition(
+ id="aws-ec2-privesc-passrole-spot-instances",
+ name="Spot Instance Launch with Privileged Role (EC2-003)",
+ short_description="Launch EC2 Spot Instances with privileged IAM roles to gain their permissions via IMDS.",
+ description="Detect principals who can pass IAM roles and request EC2 Spot Instances. This allows launching a spot instance with a privileged role attached, gaining that role's permissions via the instance metadata service.",
+ attribution=AttackPathsQueryAttribution(
+ text="pathfinding.cloud - EC2-003 - iam:PassRole + ec2:RequestSpotInstances",
+ link="https://pathfinding.cloud/paths/ec2-003",
+ ),
+ provider="aws",
+ cypher=f"""
+ // Find principals with iam:PassRole permission
+ MATCH path_principal = (aws:AWSAccount {{id: $provider_uid}})--(principal:AWSPrincipal)--(passrole_policy:AWSPolicy)--(stmt_passrole:AWSPolicyStatement)
+ WHERE stmt_passrole.effect = 'Allow'
+ AND any(action IN stmt_passrole.action WHERE
+ toLower(action) = 'iam:passrole'
+ OR toLower(action) = 'iam:*'
+ OR action = '*'
+ )
+
+ // Find ec2:RequestSpotInstances permission
+ MATCH (principal)--(spot_policy:AWSPolicy)--(stmt_spot:AWSPolicyStatement)
+ WHERE stmt_spot.effect = 'Allow'
+ AND any(action IN stmt_spot.action WHERE
+ toLower(action) = 'ec2:requestspotinstances'
+ OR toLower(action) = 'ec2:*'
+ OR action = '*'
+ )
+
+ // Find roles that trust EC2 service (can be passed to EC2 spot instances)
+ MATCH path_target = (aws)--(target_role:AWSRole)-[:TRUSTS_AWS_PRINCIPAL]->(:AWSPrincipal {{arn: 'ec2.amazonaws.com'}})
+ WHERE any(resource IN stmt_passrole.resource WHERE
+ resource = '*'
+ OR target_role.arn CONTAINS resource
+ OR resource CONTAINS target_role.name
+ )
+
+ UNWIND nodes(path_principal) + nodes(path_target) as n
+ OPTIONAL MATCH (n)-[pfr]-(pf:{PROWLER_FINDING_LABEL} {{status: 'FAIL', provider_uid: $provider_uid}})
+
+ RETURN path_principal, path_target,
+ collect(DISTINCT pf) as dpf, collect(DISTINCT pfr) as dpfr
+ """,
+ parameters=[],
+)
+
+# EC2-004
+AWS_EC2_PRIVESC_LAUNCH_TEMPLATE = AttackPathsQueryDefinition(
+ id="aws-ec2-privesc-launch-template",
+ name="Launch Template Poisoning for Role Access (EC2-004)",
+ short_description="Inject malicious userData into launch templates that reference privileged roles, no PassRole needed.",
+ description="Detect principals who can create new launch template versions and modify launch templates. This allows injecting malicious user data into existing templates that already reference privileged IAM roles, without requiring iam:PassRole permissions.",
+ attribution=AttackPathsQueryAttribution(
+ text="pathfinding.cloud - EC2-004 - ec2:CreateLaunchTemplateVersion + ec2:ModifyLaunchTemplate",
+ link="https://pathfinding.cloud/paths/ec2-004",
+ ),
+ provider="aws",
+ cypher=f"""
+ // Find principals with ec2:CreateLaunchTemplateVersion permission
+ MATCH path_principal = (aws:AWSAccount {{id: $provider_uid}})--(principal:AWSPrincipal)--(create_policy:AWSPolicy)--(stmt_create:AWSPolicyStatement)
+ WHERE stmt_create.effect = 'Allow'
+ AND any(action IN stmt_create.action WHERE
+ toLower(action) = 'ec2:createlaunchtemplateversion'
+ OR toLower(action) = 'ec2:*'
+ OR action = '*'
+ )
+
+ // Find ec2:ModifyLaunchTemplate permission
+ MATCH (principal)--(modify_policy:AWSPolicy)--(stmt_modify:AWSPolicyStatement)
+ WHERE stmt_modify.effect = 'Allow'
+ AND any(action IN stmt_modify.action WHERE
+ toLower(action) = 'ec2:modifylaunchtemplate'
+ OR toLower(action) = 'ec2:*'
+ OR action = '*'
+ )
+
+ // Find launch templates in the account (potential targets)
+ MATCH path_target = (aws)--(template:LaunchTemplate)
+
+ UNWIND nodes(path_principal) + nodes(path_target) as n
+ OPTIONAL MATCH (n)-[pfr]-(pf:{PROWLER_FINDING_LABEL} {{status: 'FAIL', provider_uid: $provider_uid}})
+
+ RETURN path_principal, path_target,
+ collect(DISTINCT pf) as dpf, collect(DISTINCT pfr) as dpfr
+ """,
+ parameters=[],
+)
+
+# EC2INSTANCECONNECT-003
+AWS_EC2INSTANCECONNECT_PRIVESC_SEND_SSH_PUBLIC_KEY = AttackPathsQueryDefinition(
+ id="aws-ec2instanceconnect-privesc-send-ssh-public-key",
+ name="EC2 Instance Connect SSH Access for Role Credentials (EC2INSTANCECONNECT-003)",
+ short_description="Push a temporary SSH key to an EC2 instance via Instance Connect to access its attached role credentials through IMDS.",
+ description="Detect principals who can send SSH public keys via EC2 Instance Connect. This allows establishing an SSH session on a running EC2 instance and retrieving the attached IAM role's temporary credentials from the Instance Metadata Service (IMDS), gaining that role's permissions.",
+ attribution=AttackPathsQueryAttribution(
+ text="pathfinding.cloud - EC2INSTANCECONNECT-003 - ec2-instance-connect:SendSSHPublicKey",
+ link="https://pathfinding.cloud/paths/ec2instanceconnect-003",
+ ),
+ provider="aws",
+ cypher=f"""
+ // Find principals with ec2-instance-connect:SendSSHPublicKey permission
+ MATCH path_principal = (aws:AWSAccount {{id: $provider_uid}})--(principal:AWSPrincipal)--(connect_policy:AWSPolicy)--(stmt_connect:AWSPolicyStatement)
+ WHERE stmt_connect.effect = 'Allow'
+ AND any(action IN stmt_connect.action WHERE
+ toLower(action) = 'ec2-instance-connect:sendsshpublickey'
+ OR toLower(action) = 'ec2-instance-connect:*'
+ OR action = '*'
+ )
+
+ // Find EC2 instances with attached roles (targets for credential theft via IMDS)
+ MATCH path_target = (aws)--(ec2:EC2Instance)-[:STS_ASSUMEROLE_ALLOW]->(target_role:AWSRole)
+
+ UNWIND nodes(path_principal) + nodes(path_target) as n
+ OPTIONAL MATCH (n)-[pfr]-(pf:{PROWLER_FINDING_LABEL} {{status: 'FAIL', provider_uid: $provider_uid}})
+
+ RETURN path_principal, path_target,
+ collect(DISTINCT pf) as dpf, collect(DISTINCT pfr) as dpfr
+ """,
+ parameters=[],
+)
+
+# ECS-001
+AWS_ECS_PRIVESC_PASSROLE_CREATE_SERVICE = AttackPathsQueryDefinition(
+ id="aws-ecs-privesc-passrole-create-service",
+ name="ECS Service Creation with Privileged Role (ECS-001 - New Cluster)",
+ short_description="Create an ECS cluster and service with a privileged Fargate task role to execute arbitrary code.",
+ description="Detect principals who can pass IAM roles, create ECS clusters, register task definitions, and create services. This allows creating a Fargate task with a privileged role attached, gaining that role's permissions to execute arbitrary code via the container.",
+ provider="aws",
+ attribution=AttackPathsQueryAttribution(
+ text="pathfinding.cloud - ECS-001 - iam:PassRole + ecs:CreateCluster + ecs:RegisterTaskDefinition + ecs:CreateService",
+ link="https://pathfinding.cloud/paths/ecs-001",
+ ),
+ cypher=f"""
+ // Find principals with iam:PassRole permission
+ MATCH path_principal = (aws:AWSAccount {{id: $provider_uid}})--(principal:AWSPrincipal)--(passrole_policy:AWSPolicy)--(stmt_passrole:AWSPolicyStatement)
+ WHERE stmt_passrole.effect = 'Allow'
+ AND any(action IN stmt_passrole.action WHERE
+ toLower(action) = 'iam:passrole'
+ OR toLower(action) = 'iam:*'
+ OR action = '*'
+ )
+
+ // Find ecs:CreateCluster permission
+ MATCH (principal)--(cluster_policy:AWSPolicy)--(stmt_cluster:AWSPolicyStatement)
+ WHERE stmt_cluster.effect = 'Allow'
+ AND any(action IN stmt_cluster.action WHERE
+ toLower(action) = 'ecs:createcluster'
+ OR toLower(action) = 'ecs:*'
+ OR action = '*'
+ )
+
+ // Find ecs:RegisterTaskDefinition permission
+ MATCH (principal)--(taskdef_policy:AWSPolicy)--(stmt_taskdef:AWSPolicyStatement)
+ WHERE stmt_taskdef.effect = 'Allow'
+ AND any(action IN stmt_taskdef.action WHERE
+ toLower(action) = 'ecs:registertaskdefinition'
+ OR toLower(action) = 'ecs:*'
+ OR action = '*'
+ )
+
+ // Find ecs:CreateService permission
+ MATCH (principal)--(service_policy:AWSPolicy)--(stmt_service:AWSPolicyStatement)
+ WHERE stmt_service.effect = 'Allow'
+ AND any(action IN stmt_service.action WHERE
+ toLower(action) = 'ecs:createservice'
+ OR toLower(action) = 'ecs:*'
+ OR action = '*'
+ )
+
+ // Find roles that trust ECS tasks service (can be passed to ECS tasks)
+ MATCH path_target = (aws)--(target_role:AWSRole)-[:TRUSTS_AWS_PRINCIPAL]->(:AWSPrincipal {{arn: 'ecs-tasks.amazonaws.com'}})
+ WHERE any(resource IN stmt_passrole.resource WHERE
+ resource = '*'
+ OR target_role.arn CONTAINS resource
+ OR resource CONTAINS target_role.name
+ )
+
+ UNWIND nodes(path_principal) + nodes(path_target) as n
+ OPTIONAL MATCH (n)-[pfr]-(pf:{PROWLER_FINDING_LABEL} {{status: 'FAIL', provider_uid: $provider_uid}})
+
+ RETURN path_principal, path_target,
+ collect(DISTINCT pf) as dpf, collect(DISTINCT pfr) as dpfr
+ """,
+ parameters=[],
+)
+
+# ECS-002
+AWS_ECS_PRIVESC_PASSROLE_RUN_TASK = AttackPathsQueryDefinition(
+ id="aws-ecs-privesc-passrole-run-task",
+ name="ECS Task Execution with Privileged Role (ECS-002 - New Cluster)",
+ short_description="Create an ECS cluster and run a one-off Fargate task with a privileged role to execute arbitrary code.",
+ description="Detect principals who can pass IAM roles, create ECS clusters, register task definitions, and run tasks. This allows creating a Fargate task with a privileged role attached, gaining that role's permissions to execute arbitrary code via the container. Unlike ecs:CreateService, ecs:RunTask executes the task once without creating a persistent service.",
+ attribution=AttackPathsQueryAttribution(
+ text="pathfinding.cloud - ECS-002 - iam:PassRole + ecs:CreateCluster + ecs:RegisterTaskDefinition + ecs:RunTask",
+ link="https://pathfinding.cloud/paths/ecs-002",
+ ),
+ provider="aws",
+ cypher=f"""
+ // Find principals with iam:PassRole permission
+ MATCH path_principal = (aws:AWSAccount {{id: $provider_uid}})--(principal:AWSPrincipal)--(passrole_policy:AWSPolicy)--(stmt_passrole:AWSPolicyStatement)
+ WHERE stmt_passrole.effect = 'Allow'
+ AND any(action IN stmt_passrole.action WHERE
+ toLower(action) = 'iam:passrole'
+ OR toLower(action) = 'iam:*'
+ OR action = '*'
+ )
+
+ // Find ecs:CreateCluster permission
+ MATCH (principal)--(cluster_policy:AWSPolicy)--(stmt_cluster:AWSPolicyStatement)
+ WHERE stmt_cluster.effect = 'Allow'
+ AND any(action IN stmt_cluster.action WHERE
+ toLower(action) = 'ecs:createcluster'
+ OR toLower(action) = 'ecs:*'
+ OR action = '*'
+ )
+
+ // Find ecs:RegisterTaskDefinition permission
+ MATCH (principal)--(taskdef_policy:AWSPolicy)--(stmt_taskdef:AWSPolicyStatement)
+ WHERE stmt_taskdef.effect = 'Allow'
+ AND any(action IN stmt_taskdef.action WHERE
+ toLower(action) = 'ecs:registertaskdefinition'
+ OR toLower(action) = 'ecs:*'
+ OR action = '*'
+ )
+
+ // Find ecs:RunTask permission
+ MATCH (principal)--(runtask_policy:AWSPolicy)--(stmt_runtask:AWSPolicyStatement)
+ WHERE stmt_runtask.effect = 'Allow'
+ AND any(action IN stmt_runtask.action WHERE
+ toLower(action) = 'ecs:runtask'
+ OR toLower(action) = 'ecs:*'
+ OR action = '*'
+ )
+
+ // Find roles that trust ECS tasks service (can be passed to ECS tasks)
+ MATCH path_target = (aws)--(target_role:AWSRole)-[:TRUSTS_AWS_PRINCIPAL]->(:AWSPrincipal {{arn: 'ecs-tasks.amazonaws.com'}})
+ WHERE any(resource IN stmt_passrole.resource WHERE
+ resource = '*'
+ OR target_role.arn CONTAINS resource
+ OR resource CONTAINS target_role.name
+ )
+
+ UNWIND nodes(path_principal) + nodes(path_target) as n
+ OPTIONAL MATCH (n)-[pfr]-(pf:{PROWLER_FINDING_LABEL} {{status: 'FAIL', provider_uid: $provider_uid}})
+
+ RETURN path_principal, path_target,
+ collect(DISTINCT pf) as dpf, collect(DISTINCT pfr) as dpfr
+ """,
+ parameters=[],
+)
+
+# ECS-003
+AWS_ECS_PRIVESC_PASSROLE_CREATE_SERVICE_EXISTING_CLUSTER = AttackPathsQueryDefinition(
+ id="aws-ecs-privesc-passrole-create-service-existing-cluster",
+ name="ECS Service Creation with Privileged Role (ECS-003 - Existing Cluster)",
+ short_description="Deploy a Fargate service with a privileged role on an existing ECS cluster.",
+ description="Detect principals who can pass IAM roles, register ECS task definitions, and create services on existing clusters. Unlike ECS-001, this does not require ecs:CreateCluster since it targets clusters that already exist. The attacker registers a task definition with a privileged role and launches it as a Fargate service, gaining that role's permissions.",
+ attribution=AttackPathsQueryAttribution(
+ text="pathfinding.cloud - ECS-003 - iam:PassRole + ecs:RegisterTaskDefinition + ecs:CreateService",
+ link="https://pathfinding.cloud/paths/ecs-003",
+ ),
+ provider="aws",
+ cypher=f"""
+ // Find principals with iam:PassRole permission
+ MATCH path_principal = (aws:AWSAccount {{id: $provider_uid}})--(principal:AWSPrincipal)--(passrole_policy:AWSPolicy)--(stmt_passrole:AWSPolicyStatement)
+ WHERE stmt_passrole.effect = 'Allow'
+ AND any(action IN stmt_passrole.action WHERE
+ toLower(action) = 'iam:passrole'
+ OR toLower(action) = 'iam:*'
+ OR action = '*'
+ )
+
+ // Find ecs:RegisterTaskDefinition permission
+ MATCH (principal)--(taskdef_policy:AWSPolicy)--(stmt_taskdef:AWSPolicyStatement)
+ WHERE stmt_taskdef.effect = 'Allow'
+ AND any(action IN stmt_taskdef.action WHERE
+ toLower(action) = 'ecs:registertaskdefinition'
+ OR toLower(action) = 'ecs:*'
+ OR action = '*'
+ )
+
+ // Find ecs:CreateService permission
+ MATCH (principal)--(service_policy:AWSPolicy)--(stmt_service:AWSPolicyStatement)
+ WHERE stmt_service.effect = 'Allow'
+ AND any(action IN stmt_service.action WHERE
+ toLower(action) = 'ecs:createservice'
+ OR toLower(action) = 'ecs:*'
+ OR action = '*'
+ )
+
+ // Find roles that trust ECS tasks service (can be passed to ECS tasks)
+ MATCH path_target = (aws)--(target_role:AWSRole)-[:TRUSTS_AWS_PRINCIPAL]->(:AWSPrincipal {{arn: 'ecs-tasks.amazonaws.com'}})
+ WHERE any(resource IN stmt_passrole.resource WHERE
+ resource = '*'
+ OR target_role.arn CONTAINS resource
+ OR resource CONTAINS target_role.name
+ )
+
+ UNWIND nodes(path_principal) + nodes(path_target) as n
+ OPTIONAL MATCH (n)-[pfr]-(pf:{PROWLER_FINDING_LABEL} {{status: 'FAIL', provider_uid: $provider_uid}})
+
+ RETURN path_principal, path_target,
+ collect(DISTINCT pf) as dpf, collect(DISTINCT pfr) as dpfr
+ """,
+ parameters=[],
+)
+
+# ECS-004
+AWS_ECS_PRIVESC_PASSROLE_RUN_TASK_EXISTING_CLUSTER = AttackPathsQueryDefinition(
+ id="aws-ecs-privesc-passrole-run-task-existing-cluster",
+ name="ECS Task Execution with Privileged Role (ECS-004 - Existing Cluster)",
+ short_description="Run a one-off Fargate task with a privileged role on an existing ECS cluster.",
+ description="Detect principals who can pass IAM roles, register ECS task definitions, and run tasks on existing clusters. Unlike ECS-002, this does not require ecs:CreateCluster since it targets clusters that already exist. The attacker registers a task definition with a privileged role and runs it as a one-off Fargate task, gaining that role's permissions.",
+ attribution=AttackPathsQueryAttribution(
+ text="pathfinding.cloud - ECS-004 - iam:PassRole + ecs:RegisterTaskDefinition + ecs:RunTask",
+ link="https://pathfinding.cloud/paths/ecs-004",
+ ),
+ provider="aws",
+ cypher=f"""
+ // Find principals with iam:PassRole permission
+ MATCH path_principal = (aws:AWSAccount {{id: $provider_uid}})--(principal:AWSPrincipal)--(passrole_policy:AWSPolicy)--(stmt_passrole:AWSPolicyStatement)
+ WHERE stmt_passrole.effect = 'Allow'
+ AND any(action IN stmt_passrole.action WHERE
+ toLower(action) = 'iam:passrole'
+ OR toLower(action) = 'iam:*'
+ OR action = '*'
+ )
+
+ // Find ecs:RegisterTaskDefinition permission
+ MATCH (principal)--(taskdef_policy:AWSPolicy)--(stmt_taskdef:AWSPolicyStatement)
+ WHERE stmt_taskdef.effect = 'Allow'
+ AND any(action IN stmt_taskdef.action WHERE
+ toLower(action) = 'ecs:registertaskdefinition'
+ OR toLower(action) = 'ecs:*'
+ OR action = '*'
+ )
+
+ // Find ecs:RunTask permission
+ MATCH (principal)--(runtask_policy:AWSPolicy)--(stmt_runtask:AWSPolicyStatement)
+ WHERE stmt_runtask.effect = 'Allow'
+ AND any(action IN stmt_runtask.action WHERE
+ toLower(action) = 'ecs:runtask'
+ OR toLower(action) = 'ecs:*'
+ OR action = '*'
+ )
+
+ // Find roles that trust ECS tasks service (can be passed to ECS tasks)
+ MATCH path_target = (aws)--(target_role:AWSRole)-[:TRUSTS_AWS_PRINCIPAL]->(:AWSPrincipal {{arn: 'ecs-tasks.amazonaws.com'}})
+ WHERE any(resource IN stmt_passrole.resource WHERE
+ resource = '*'
+ OR target_role.arn CONTAINS resource
+ OR resource CONTAINS target_role.name
+ )
+
+ UNWIND nodes(path_principal) + nodes(path_target) as n
+ OPTIONAL MATCH (n)-[pfr]-(pf:{PROWLER_FINDING_LABEL} {{status: 'FAIL', provider_uid: $provider_uid}})
+
+ RETURN path_principal, path_target,
+ collect(DISTINCT pf) as dpf, collect(DISTINCT pfr) as dpfr
+ """,
+ parameters=[],
+)
+
+# ECS-005
+AWS_ECS_PRIVESC_PASSROLE_START_TASK_EXISTING_CLUSTER = AttackPathsQueryDefinition(
+ id="aws-ecs-privesc-passrole-start-task-existing-cluster",
+ name="ECS Task Start with Privileged Role on EC2 (ECS-005 - Existing Cluster)",
+ short_description="Register a task definition with a privileged role and start it on an EC2 container instance to execute arbitrary code.",
+ description="Detect principals who can pass IAM roles, register ECS task definitions, and start tasks on existing EC2 container instances. Unlike ecs:RunTask which works with both EC2 and Fargate, ecs:StartTask is specific to EC2 launch types and requires specifying an existing container instance ARN. The attacker registers a task definition with a privileged role and starts it on a container instance, gaining that role's permissions.",
+ attribution=AttackPathsQueryAttribution(
+ text="pathfinding.cloud - ECS-005 - iam:PassRole + ecs:RegisterTaskDefinition + ecs:StartTask",
+ link="https://pathfinding.cloud/paths/ecs-005",
+ ),
+ provider="aws",
+ cypher=f"""
+ // Find principals with iam:PassRole permission
+ MATCH path_principal = (aws:AWSAccount {{id: $provider_uid}})--(principal:AWSPrincipal)--(passrole_policy:AWSPolicy)--(stmt_passrole:AWSPolicyStatement)
+ WHERE stmt_passrole.effect = 'Allow'
+ AND any(action IN stmt_passrole.action WHERE
+ toLower(action) = 'iam:passrole'
+ OR toLower(action) = 'iam:*'
+ OR action = '*'
+ )
+
+ // Find ecs:RegisterTaskDefinition permission
+ MATCH (principal)--(taskdef_policy:AWSPolicy)--(stmt_taskdef:AWSPolicyStatement)
+ WHERE stmt_taskdef.effect = 'Allow'
+ AND any(action IN stmt_taskdef.action WHERE
+ toLower(action) = 'ecs:registertaskdefinition'
+ OR toLower(action) = 'ecs:*'
+ OR action = '*'
+ )
+
+ // Find ecs:StartTask permission
+ MATCH (principal)--(starttask_policy:AWSPolicy)--(stmt_starttask:AWSPolicyStatement)
+ WHERE stmt_starttask.effect = 'Allow'
+ AND any(action IN stmt_starttask.action WHERE
+ toLower(action) = 'ecs:starttask'
+ OR toLower(action) = 'ecs:*'
+ OR action = '*'
+ )
+
+ // Find roles that trust ECS tasks service (can be passed to ECS tasks)
+ MATCH path_target = (aws)--(target_role:AWSRole)-[:TRUSTS_AWS_PRINCIPAL]->(:AWSPrincipal {{arn: 'ecs-tasks.amazonaws.com'}})
+ WHERE any(resource IN stmt_passrole.resource WHERE
+ resource = '*'
+ OR target_role.arn CONTAINS resource
+ OR resource CONTAINS target_role.name
+ )
+
+ UNWIND nodes(path_principal) + nodes(path_target) as n
+ OPTIONAL MATCH (n)-[pfr]-(pf:{PROWLER_FINDING_LABEL} {{status: 'FAIL', provider_uid: $provider_uid}})
+
+ RETURN path_principal, path_target,
+ collect(DISTINCT pf) as dpf, collect(DISTINCT pfr) as dpfr
+ """,
+ parameters=[],
+)
+
+# ECS-006
+AWS_ECS_PRIVESC_EXECUTE_COMMAND = AttackPathsQueryDefinition(
+ id="aws-ecs-privesc-execute-command",
+ name="ECS Exec Container Hijacking for Role Credentials (ECS-006)",
+ short_description="Shell into a running ECS container via ECS Exec to steal the attached task role's credentials.",
+ description="Detect principals who can execute commands in running ECS containers and describe tasks. This allows establishing an interactive shell session in a container where ECS Exec is enabled, then retrieving the task role's temporary credentials from the container metadata service, without requiring iam:PassRole.",
+ attribution=AttackPathsQueryAttribution(
+ text="pathfinding.cloud - ECS-006 - ecs:ExecuteCommand + ecs:DescribeTasks",
+ link="https://pathfinding.cloud/paths/ecs-006",
+ ),
+ provider="aws",
+ cypher=f"""
+ // Find principals with ecs:ExecuteCommand permission
+ MATCH path_principal = (aws:AWSAccount {{id: $provider_uid}})--(principal:AWSPrincipal)--(exec_policy:AWSPolicy)--(stmt_exec:AWSPolicyStatement)
+ WHERE stmt_exec.effect = 'Allow'
+ AND any(action IN stmt_exec.action WHERE
+ toLower(action) = 'ecs:executecommand'
+ OR toLower(action) = 'ecs:*'
+ OR action = '*'
+ )
+
+ // Find ecs:DescribeTasks permission (required by AWS CLI to get container runtime ID)
+ MATCH (principal)--(describe_policy:AWSPolicy)--(stmt_describe:AWSPolicyStatement)
+ WHERE stmt_describe.effect = 'Allow'
+ AND any(action IN stmt_describe.action WHERE
+ toLower(action) = 'ecs:describetasks'
+ OR toLower(action) = 'ecs:*'
+ OR action = '*'
+ )
+
+ // Find roles that trust ECS tasks service (already attached to running tasks)
+ MATCH path_target = (aws)--(target_role:AWSRole)-[:TRUSTS_AWS_PRINCIPAL]->(:AWSPrincipal {{arn: 'ecs-tasks.amazonaws.com'}})
+
+ UNWIND nodes(path_principal) + nodes(path_target) as n
+ OPTIONAL MATCH (n)-[pfr]-(pf:{PROWLER_FINDING_LABEL} {{status: 'FAIL', provider_uid: $provider_uid}})
+
+ RETURN path_principal, path_target,
+ collect(DISTINCT pf) as dpf, collect(DISTINCT pfr) as dpfr
+ """,
+ parameters=[],
+)
+
+# GLUE-001
+AWS_GLUE_PRIVESC_PASSROLE_DEV_ENDPOINT = AttackPathsQueryDefinition(
+ id="aws-glue-privesc-passrole-dev-endpoint",
+ name="Glue Dev Endpoint with Privileged Role (GLUE-001)",
+ short_description="Create a Glue development endpoint with a privileged role attached to gain its permissions.",
+ description="Detect principals who can pass IAM roles and create Glue development endpoints. This allows creating a dev endpoint with a privileged role attached, gaining that role's permissions.",
+ attribution=AttackPathsQueryAttribution(
+ text="pathfinding.cloud - GLUE-001 - iam:PassRole + glue:CreateDevEndpoint",
+ link="https://pathfinding.cloud/paths/glue-001",
+ ),
+ provider="aws",
+ cypher=f"""
+ // Find principals with iam:PassRole permission
+ MATCH path_principal = (aws:AWSAccount {{id: $provider_uid}})--(principal:AWSPrincipal)--(passrole_policy:AWSPolicy)--(stmt_passrole:AWSPolicyStatement)
+ WHERE stmt_passrole.effect = 'Allow'
+ AND any(action IN stmt_passrole.action WHERE
+ toLower(action) = 'iam:passrole'
+ OR toLower(action) = 'iam:*'
+ OR action = '*'
+ )
+
+ // Find glue:CreateDevEndpoint permission
+ MATCH (principal)--(glue_policy:AWSPolicy)--(stmt_glue:AWSPolicyStatement)
+ WHERE stmt_glue.effect = 'Allow'
+ AND any(action IN stmt_glue.action WHERE
+ toLower(action) = 'glue:createdevendpoint'
+ OR toLower(action) = 'glue:*'
+ OR action = '*'
+ )
+
+ // Find roles that trust Glue service (can be passed to Glue)
+ MATCH path_target = (aws)--(target_role:AWSRole)-[:TRUSTS_AWS_PRINCIPAL]->(:AWSPrincipal {{arn: 'glue.amazonaws.com'}})
+ WHERE any(resource IN stmt_passrole.resource WHERE
+ resource = '*'
+ OR target_role.arn CONTAINS resource
+ OR resource CONTAINS target_role.name
+ )
+
+ UNWIND nodes(path_principal) + nodes(path_target) as n
+ OPTIONAL MATCH (n)-[pfr]-(pf:{PROWLER_FINDING_LABEL} {{status: 'FAIL', provider_uid: $provider_uid}})
+
+ RETURN path_principal, path_target,
+ collect(DISTINCT pf) as dpf, collect(DISTINCT pfr) as dpfr
+ """,
+ parameters=[],
+)
+
+# GLUE-002
+AWS_GLUE_PRIVESC_UPDATE_DEV_ENDPOINT = AttackPathsQueryDefinition(
+ id="aws-glue-privesc-update-dev-endpoint",
+ name="Glue Dev Endpoint SSH Hijacking via Update (GLUE-002)",
+ short_description="Update an existing Glue development endpoint to inject an SSH public key and access its attached role credentials.",
+ description="Detect principals who can update Glue development endpoints. This allows adding an attacker-controlled SSH public key to an existing dev endpoint that already has a privileged role attached, then SSHing into it to steal the role's temporary credentials without requiring iam:PassRole.",
+ attribution=AttackPathsQueryAttribution(
+ text="pathfinding.cloud - GLUE-002 - glue:UpdateDevEndpoint",
+ link="https://pathfinding.cloud/paths/glue-002",
+ ),
+ provider="aws",
+ cypher=f"""
+ // Find principals with glue:UpdateDevEndpoint permission
+ MATCH path_principal = (aws:AWSAccount {{id: $provider_uid}})--(principal:AWSPrincipal)--(policy:AWSPolicy)--(stmt:AWSPolicyStatement)
+ WHERE stmt.effect = 'Allow'
+ AND any(action IN stmt.action WHERE
+ toLower(action) = 'glue:updatedevendpoint'
+ OR toLower(action) = 'glue:*'
+ OR action = '*'
+ )
+
+ // Find roles that trust Glue service (already attached to existing dev endpoints)
+ MATCH path_target = (aws)--(target_role:AWSRole)-[:TRUSTS_AWS_PRINCIPAL]->(:AWSPrincipal {{arn: 'glue.amazonaws.com'}})
+
+ UNWIND nodes(path_principal) + nodes(path_target) as n
+ OPTIONAL MATCH (n)-[pfr]-(pf:{PROWLER_FINDING_LABEL} {{status: 'FAIL', provider_uid: $provider_uid}})
+
+ RETURN path_principal, path_target,
+ collect(DISTINCT pf) as dpf, collect(DISTINCT pfr) as dpfr
+ """,
+ parameters=[],
+)
+
+# GLUE-003
+AWS_GLUE_PRIVESC_PASSROLE_CREATE_JOB = AttackPathsQueryDefinition(
+ id="aws-glue-privesc-passrole-create-job",
+ name="Glue Job Creation with Privileged Role (GLUE-003)",
+ short_description="Create a Glue job with a privileged role and start it to execute arbitrary code with that role's permissions.",
+ description="Detect principals who can pass IAM roles, create Glue jobs, and start job runs. This allows creating a Python shell job with a privileged role attached and executing arbitrary code that modifies IAM permissions, a cost-effective alternative to Glue development endpoints.",
+ attribution=AttackPathsQueryAttribution(
+ text="pathfinding.cloud - GLUE-003 - iam:PassRole + glue:CreateJob + glue:StartJobRun",
+ link="https://pathfinding.cloud/paths/glue-003",
+ ),
+ provider="aws",
+ cypher=f"""
+ // Find principals with iam:PassRole permission
+ MATCH path_principal = (aws:AWSAccount {{id: $provider_uid}})--(principal:AWSPrincipal)--(passrole_policy:AWSPolicy)--(stmt_passrole:AWSPolicyStatement)
+ WHERE stmt_passrole.effect = 'Allow'
+ AND any(action IN stmt_passrole.action WHERE
+ toLower(action) = 'iam:passrole'
+ OR toLower(action) = 'iam:*'
+ OR action = '*'
+ )
+
+ // Find glue:CreateJob permission
+ MATCH (principal)--(createjob_policy:AWSPolicy)--(stmt_createjob:AWSPolicyStatement)
+ WHERE stmt_createjob.effect = 'Allow'
+ AND any(action IN stmt_createjob.action WHERE
+ toLower(action) = 'glue:createjob'
+ OR toLower(action) = 'glue:*'
+ OR action = '*'
+ )
+
+ // Find glue:StartJobRun permission
+ MATCH (principal)--(startjob_policy:AWSPolicy)--(stmt_startjob:AWSPolicyStatement)
+ WHERE stmt_startjob.effect = 'Allow'
+ AND any(action IN stmt_startjob.action WHERE
+ toLower(action) = 'glue:startjobrun'
+ OR toLower(action) = 'glue:*'
+ OR action = '*'
+ )
+
+ // Find roles that trust Glue service (can be passed to Glue jobs)
+ MATCH path_target = (aws)--(target_role:AWSRole)-[:TRUSTS_AWS_PRINCIPAL]->(:AWSPrincipal {{arn: 'glue.amazonaws.com'}})
+ WHERE any(resource IN stmt_passrole.resource WHERE
+ resource = '*'
+ OR target_role.arn CONTAINS resource
+ OR resource CONTAINS target_role.name
+ )
+
+ UNWIND nodes(path_principal) + nodes(path_target) as n
+ OPTIONAL MATCH (n)-[pfr]-(pf:{PROWLER_FINDING_LABEL} {{status: 'FAIL', provider_uid: $provider_uid}})
+
+ RETURN path_principal, path_target,
+ collect(DISTINCT pf) as dpf, collect(DISTINCT pfr) as dpfr
+ """,
+ parameters=[],
+)
+
+# GLUE-004
+AWS_GLUE_PRIVESC_PASSROLE_CREATE_JOB_TRIGGER = AttackPathsQueryDefinition(
+ id="aws-glue-privesc-passrole-create-job-trigger",
+ name="Glue Job Creation with Scheduled Trigger and Privileged Role (GLUE-004)",
+ short_description="Create a Glue job with a privileged role and a scheduled trigger to persistently execute arbitrary code.",
+ description="Detect principals who can pass IAM roles, create Glue jobs, and create triggers with automatic activation. Unlike manual execution via StartJobRun, this creates a persistent attack by scheduling the job to run repeatedly, making it harder to detect and remediate.",
+ attribution=AttackPathsQueryAttribution(
+ text="pathfinding.cloud - GLUE-004 - iam:PassRole + glue:CreateJob + glue:CreateTrigger",
+ link="https://pathfinding.cloud/paths/glue-004",
+ ),
+ provider="aws",
+ cypher=f"""
+ // Find principals with iam:PassRole permission
+ MATCH path_principal = (aws:AWSAccount {{id: $provider_uid}})--(principal:AWSPrincipal)--(passrole_policy:AWSPolicy)--(stmt_passrole:AWSPolicyStatement)
+ WHERE stmt_passrole.effect = 'Allow'
+ AND any(action IN stmt_passrole.action WHERE
+ toLower(action) = 'iam:passrole'
+ OR toLower(action) = 'iam:*'
+ OR action = '*'
+ )
+
+ // Find glue:CreateJob permission
+ MATCH (principal)--(createjob_policy:AWSPolicy)--(stmt_createjob:AWSPolicyStatement)
+ WHERE stmt_createjob.effect = 'Allow'
+ AND any(action IN stmt_createjob.action WHERE
+ toLower(action) = 'glue:createjob'
+ OR toLower(action) = 'glue:*'
+ OR action = '*'
+ )
+
+ // Find glue:CreateTrigger permission
+ MATCH (principal)--(trigger_policy:AWSPolicy)--(stmt_trigger:AWSPolicyStatement)
+ WHERE stmt_trigger.effect = 'Allow'
+ AND any(action IN stmt_trigger.action WHERE
+ toLower(action) = 'glue:createtrigger'
+ OR toLower(action) = 'glue:*'
+ OR action = '*'
+ )
+
+ // Find roles that trust Glue service (can be passed to Glue jobs)
+ MATCH path_target = (aws)--(target_role:AWSRole)-[:TRUSTS_AWS_PRINCIPAL]->(:AWSPrincipal {{arn: 'glue.amazonaws.com'}})
+ WHERE any(resource IN stmt_passrole.resource WHERE
+ resource = '*'
+ OR target_role.arn CONTAINS resource
+ OR resource CONTAINS target_role.name
+ )
+
+ UNWIND nodes(path_principal) + nodes(path_target) as n
+ OPTIONAL MATCH (n)-[pfr]-(pf:{PROWLER_FINDING_LABEL} {{status: 'FAIL', provider_uid: $provider_uid}})
+
+ RETURN path_principal, path_target,
+ collect(DISTINCT pf) as dpf, collect(DISTINCT pfr) as dpfr
+ """,
+ parameters=[],
+)
+
+# GLUE-005
+AWS_GLUE_PRIVESC_PASSROLE_UPDATE_JOB = AttackPathsQueryDefinition(
+ id="aws-glue-privesc-passrole-update-job",
+ name="Glue Job Hijacking via Update with Privileged Role (GLUE-005)",
+ short_description="Update an existing Glue job to attach a privileged role and inject malicious code, then start it to gain that role's permissions.",
+ description="Detect principals who can pass IAM roles, update existing Glue jobs, and start job runs. This allows modifying an existing job's role and script to execute arbitrary code with elevated privileges, a stealthier variant of job creation since it reuses existing infrastructure rather than creating new resources.",
+ attribution=AttackPathsQueryAttribution(
+ text="pathfinding.cloud - GLUE-005 - iam:PassRole + glue:UpdateJob + glue:StartJobRun",
+ link="https://pathfinding.cloud/paths/glue-005",
+ ),
+ provider="aws",
+ cypher=f"""
+ // Find principals with iam:PassRole permission
+ MATCH path_principal = (aws:AWSAccount {{id: $provider_uid}})--(principal:AWSPrincipal)--(passrole_policy:AWSPolicy)--(stmt_passrole:AWSPolicyStatement)
+ WHERE stmt_passrole.effect = 'Allow'
+ AND any(action IN stmt_passrole.action WHERE
+ toLower(action) = 'iam:passrole'
+ OR toLower(action) = 'iam:*'
+ OR action = '*'
+ )
+
+ // Find glue:UpdateJob permission
+ MATCH (principal)--(updatejob_policy:AWSPolicy)--(stmt_updatejob:AWSPolicyStatement)
+ WHERE stmt_updatejob.effect = 'Allow'
+ AND any(action IN stmt_updatejob.action WHERE
+ toLower(action) = 'glue:updatejob'
+ OR toLower(action) = 'glue:*'
+ OR action = '*'
+ )
+
+ // Find glue:StartJobRun permission
+ MATCH (principal)--(startjob_policy:AWSPolicy)--(stmt_startjob:AWSPolicyStatement)
+ WHERE stmt_startjob.effect = 'Allow'
+ AND any(action IN stmt_startjob.action WHERE
+ toLower(action) = 'glue:startjobrun'
+ OR toLower(action) = 'glue:*'
+ OR action = '*'
+ )
+
+ // Find roles that trust Glue service (can be passed to Glue jobs)
+ MATCH path_target = (aws)--(target_role:AWSRole)-[:TRUSTS_AWS_PRINCIPAL]->(:AWSPrincipal {{arn: 'glue.amazonaws.com'}})
+ WHERE any(resource IN stmt_passrole.resource WHERE
+ resource = '*'
+ OR target_role.arn CONTAINS resource
+ OR resource CONTAINS target_role.name
+ )
+
+ UNWIND nodes(path_principal) + nodes(path_target) as n
+ OPTIONAL MATCH (n)-[pfr]-(pf:{PROWLER_FINDING_LABEL} {{status: 'FAIL', provider_uid: $provider_uid}})
+
+ RETURN path_principal, path_target,
+ collect(DISTINCT pf) as dpf, collect(DISTINCT pfr) as dpfr
+ """,
+ parameters=[],
+)
+
+# GLUE-006
+AWS_GLUE_PRIVESC_PASSROLE_UPDATE_JOB_TRIGGER = AttackPathsQueryDefinition(
+ id="aws-glue-privesc-passrole-update-job-trigger",
+ name="Glue Job Hijacking with Scheduled Trigger and Privileged Role (GLUE-006)",
+ short_description="Update an existing Glue job to attach a privileged role and inject malicious code, then create a scheduled trigger for persistent automated execution.",
+ description="Detect principals who can pass IAM roles, update existing Glue jobs, and create triggers with automatic activation. This combines the stealth of modifying existing infrastructure with the persistence of scheduled automation, creating a recurring backdoor that re-executes even after remediation attempts.",
+ attribution=AttackPathsQueryAttribution(
+ text="pathfinding.cloud - GLUE-006 - iam:PassRole + glue:UpdateJob + glue:CreateTrigger",
+ link="https://pathfinding.cloud/paths/glue-006",
+ ),
+ provider="aws",
+ cypher=f"""
+ // Find principals with iam:PassRole permission
+ MATCH path_principal = (aws:AWSAccount {{id: $provider_uid}})--(principal:AWSPrincipal)--(passrole_policy:AWSPolicy)--(stmt_passrole:AWSPolicyStatement)
+ WHERE stmt_passrole.effect = 'Allow'
+ AND any(action IN stmt_passrole.action WHERE
+ toLower(action) = 'iam:passrole'
+ OR toLower(action) = 'iam:*'
+ OR action = '*'
+ )
+
+ // Find glue:UpdateJob permission
+ MATCH (principal)--(updatejob_policy:AWSPolicy)--(stmt_updatejob:AWSPolicyStatement)
+ WHERE stmt_updatejob.effect = 'Allow'
+ AND any(action IN stmt_updatejob.action WHERE
+ toLower(action) = 'glue:updatejob'
+ OR toLower(action) = 'glue:*'
+ OR action = '*'
+ )
+
+ // Find glue:CreateTrigger permission
+ MATCH (principal)--(trigger_policy:AWSPolicy)--(stmt_trigger:AWSPolicyStatement)
+ WHERE stmt_trigger.effect = 'Allow'
+ AND any(action IN stmt_trigger.action WHERE
+ toLower(action) = 'glue:createtrigger'
+ OR toLower(action) = 'glue:*'
+ OR action = '*'
+ )
+
+ // Find roles that trust Glue service (can be passed to Glue jobs)
+ MATCH path_target = (aws)--(target_role:AWSRole)-[:TRUSTS_AWS_PRINCIPAL]->(:AWSPrincipal {{arn: 'glue.amazonaws.com'}})
+ WHERE any(resource IN stmt_passrole.resource WHERE
+ resource = '*'
+ OR target_role.arn CONTAINS resource
+ OR resource CONTAINS target_role.name
+ )
+
+ UNWIND nodes(path_principal) + nodes(path_target) as n
+ OPTIONAL MATCH (n)-[pfr]-(pf:{PROWLER_FINDING_LABEL} {{status: 'FAIL', provider_uid: $provider_uid}})
+
+ RETURN path_principal, path_target,
+ collect(DISTINCT pf) as dpf, collect(DISTINCT pfr) as dpfr
+ """,
+ parameters=[],
+)
+
+# IAM-001
+AWS_IAM_PRIVESC_CREATE_POLICY_VERSION = AttackPathsQueryDefinition(
+ id="aws-iam-privesc-create-policy-version",
+ name="Policy Version Override for Self-Escalation (IAM-001)",
+ short_description="Create a new version of an attached policy with administrative permissions, instantly escalating the principal's own privileges.",
+ description="Detect principals who can create new policy versions. If a customer-managed policy is already attached to a principal and that principal has iam:CreatePolicyVersion on that policy, they can replace its contents with a fully permissive policy and set it as the default, gaining immediate administrative access.",
+ attribution=AttackPathsQueryAttribution(
+ text="pathfinding.cloud - IAM-001 - iam:CreatePolicyVersion",
+ link="https://pathfinding.cloud/paths/iam-001",
+ ),
+ provider="aws",
+ cypher=f"""
+ // Find principals with iam:CreatePolicyVersion permission
+ MATCH path_principal = (aws:AWSAccount {{id: $provider_uid}})--(principal:AWSPrincipal)--(policy:AWSPolicy)--(stmt:AWSPolicyStatement)
+ WHERE stmt.effect = 'Allow'
+ AND any(action IN stmt.action WHERE
+ toLower(action) = 'iam:createpolicyversion'
+ OR toLower(action) = 'iam:*'
+ OR action = '*'
+ )
+
+ // Find customer-managed policies attached to the same principal that can be overwritten
+ MATCH path_target = (aws)--(target_policy:AWSPolicy)--(principal)
+ WHERE target_policy.arn CONTAINS $provider_uid
+ AND any(resource IN stmt.resource WHERE
+ resource = '*'
+ OR target_policy.arn CONTAINS resource
+ )
+
+ UNWIND nodes(path_principal) + nodes(path_target) as n
+ OPTIONAL MATCH (n)-[pfr]-(pf:{PROWLER_FINDING_LABEL} {{status: 'FAIL', provider_uid: $provider_uid}})
+
+ RETURN path_principal, path_target,
+ collect(DISTINCT pf) as dpf, collect(DISTINCT pfr) as dpfr
+ """,
+ parameters=[],
+)
+
+# IAM-002
+AWS_IAM_PRIVESC_CREATE_ACCESS_KEY = AttackPathsQueryDefinition(
+ id="aws-iam-privesc-create-access-key",
+ name="Access Key Creation for Lateral Movement (IAM-002)",
+ short_description="Create access keys for other IAM users to gain their permissions and move laterally across the account.",
+ description="Detect principals who can create access keys for other IAM users. This allows generating new credentials for any target user within the resource scope, immediately gaining that user's permissions without needing their password or existing keys.",
+ attribution=AttackPathsQueryAttribution(
+ text="pathfinding.cloud - IAM-002 - iam:CreateAccessKey",
+ link="https://pathfinding.cloud/paths/iam-002",
+ ),
+ provider="aws",
+ cypher=f"""
+ // Find principals with iam:CreateAccessKey permission
+ MATCH path_principal = (aws:AWSAccount {{id: $provider_uid}})--(principal:AWSPrincipal)--(policy:AWSPolicy)--(stmt:AWSPolicyStatement)
+ WHERE stmt.effect = 'Allow'
+ AND any(action IN stmt.action WHERE
+ toLower(action) = 'iam:createaccesskey'
+ OR toLower(action) = 'iam:*'
+ OR action = '*'
+ )
+
+ // Find target users that the principal can create access keys for
+ MATCH path_target = (aws)--(target_user:AWSUser)
+ WHERE any(resource IN stmt.resource WHERE
+ resource = '*'
+ OR target_user.arn CONTAINS resource
+ OR resource CONTAINS target_user.name
+ )
+
+ UNWIND nodes(path_principal) + nodes(path_target) as n
+ OPTIONAL MATCH (n)-[pfr]-(pf:{PROWLER_FINDING_LABEL} {{status: 'FAIL', provider_uid: $provider_uid}})
+
+ RETURN path_principal, path_target,
+ collect(DISTINCT pf) as dpf, collect(DISTINCT pfr) as dpfr
+ """,
+ parameters=[],
+)
+
+# IAM-003
+AWS_IAM_PRIVESC_DELETE_CREATE_ACCESS_KEY = AttackPathsQueryDefinition(
+ id="aws-iam-privesc-delete-create-access-key",
+ name="Access Key Rotation Attack for Lateral Movement (IAM-003)",
+ short_description="Delete and recreate access keys for other IAM users to bypass the two-key limit and gain their permissions.",
+ description="Detect principals who can both delete and create access keys for other IAM users. This variation of IAM-002 handles the scenario where a target user already has the maximum of two access keys by first deleting one, then creating a replacement under the attacker's control.",
+ attribution=AttackPathsQueryAttribution(
+ text="pathfinding.cloud - IAM-003 - iam:CreateAccessKey + iam:DeleteAccessKey",
+ link="https://pathfinding.cloud/paths/iam-003",
+ ),
+ provider="aws",
+ cypher=f"""
+ // Find principals with iam:CreateAccessKey permission
+ MATCH path_principal = (aws:AWSAccount {{id: $provider_uid}})--(principal:AWSPrincipal)--(policy:AWSPolicy)--(stmt:AWSPolicyStatement)
+ WHERE stmt.effect = 'Allow'
+ AND any(action IN stmt.action WHERE
+ toLower(action) = 'iam:createaccesskey'
+ OR toLower(action) = 'iam:*'
+ OR action = '*'
+ )
+
+ // Find iam:DeleteAccessKey permission
+ MATCH (principal)--(delete_policy:AWSPolicy)--(stmt_delete:AWSPolicyStatement)
+ WHERE stmt_delete.effect = 'Allow'
+ AND any(action IN stmt_delete.action WHERE
+ toLower(action) = 'iam:deleteaccesskey'
+ OR toLower(action) = 'iam:*'
+ OR action = '*'
+ )
+
+ // Find target users that the principal can rotate access keys for
+ MATCH path_target = (aws)--(target_user:AWSUser)
+ WHERE any(resource IN stmt.resource WHERE
+ resource = '*'
+ OR target_user.arn CONTAINS resource
+ OR resource CONTAINS target_user.name
+ )
+ AND any(resource IN stmt_delete.resource WHERE
+ resource = '*'
+ OR target_user.arn CONTAINS resource
+ OR resource CONTAINS target_user.name
+ )
+
+ UNWIND nodes(path_principal) + nodes(path_target) as n
+ OPTIONAL MATCH (n)-[pfr]-(pf:{PROWLER_FINDING_LABEL} {{status: 'FAIL', provider_uid: $provider_uid}})
+
+ RETURN path_principal, path_target,
+ collect(DISTINCT pf) as dpf, collect(DISTINCT pfr) as dpfr
+ """,
+ parameters=[],
+)
+
+# IAM-004
+AWS_IAM_PRIVESC_CREATE_LOGIN_PROFILE = AttackPathsQueryDefinition(
+ id="aws-iam-privesc-create-login-profile",
+ name="Console Login Profile Creation for Lateral Movement (IAM-004)",
+ short_description="Create console login profiles for other IAM users to access the AWS Console with their permissions.",
+ description="Detect principals who can create console login profiles for other IAM users. By setting a known password on a target user that lacks a login profile, the attacker gains AWS Console access with that user's permissions without needing their existing credentials.",
+ attribution=AttackPathsQueryAttribution(
+ text="pathfinding.cloud - IAM-004 - iam:CreateLoginProfile",
+ link="https://pathfinding.cloud/paths/iam-004",
+ ),
+ provider="aws",
+ cypher=f"""
+ // Find principals with iam:CreateLoginProfile permission
+ MATCH path_principal = (aws:AWSAccount {{id: $provider_uid}})--(principal:AWSPrincipal)--(policy:AWSPolicy)--(stmt:AWSPolicyStatement)
+ WHERE stmt.effect = 'Allow'
+ AND any(action IN stmt.action WHERE
+ toLower(action) = 'iam:createloginprofile'
+ OR toLower(action) = 'iam:*'
+ OR action = '*'
+ )
+
+ // Find target users that the principal can create login profiles for
+ MATCH path_target = (aws)--(target_user:AWSUser)
+ WHERE any(resource IN stmt.resource WHERE
+ resource = '*'
+ OR target_user.arn CONTAINS resource
+ OR resource CONTAINS target_user.name
+ )
+
+ UNWIND nodes(path_principal) + nodes(path_target) as n
+ OPTIONAL MATCH (n)-[pfr]-(pf:{PROWLER_FINDING_LABEL} {{status: 'FAIL', provider_uid: $provider_uid}})
+
+ RETURN path_principal, path_target,
+ collect(DISTINCT pf) as dpf, collect(DISTINCT pfr) as dpfr
+ """,
+ parameters=[],
+)
+
+# IAM-005
+AWS_IAM_PRIVESC_PUT_ROLE_POLICY = AttackPathsQueryDefinition(
+ id="aws-iam-privesc-put-role-policy",
+ name="Inline Policy Injection for Self-Escalation (IAM-005)",
+ short_description="Attach an inline policy with administrative permissions to your own role, instantly escalating privileges.",
+ description="Detect roles that can use iam:PutRolePolicy on themselves. A role with this permission can attach an inline policy granting any permissions, including full administrative access, without needing to modify or assume any other resource.",
+ attribution=AttackPathsQueryAttribution(
+ text="pathfinding.cloud - IAM-005 - iam:PutRolePolicy",
+ link="https://pathfinding.cloud/paths/iam-005",
+ ),
+ provider="aws",
+ cypher=f"""
+ // Find roles with iam:PutRolePolicy permission scoped to themselves
+ MATCH path_principal = (aws:AWSAccount {{id: $provider_uid}})--(role:AWSRole)--(policy:AWSPolicy)--(stmt:AWSPolicyStatement)
+ WHERE stmt.effect = 'Allow'
+ AND any(action IN stmt.action WHERE
+ toLower(action) = 'iam:putrolepolicy'
+ OR toLower(action) = 'iam:*'
+ OR action = '*'
+ )
+ AND any(resource IN stmt.resource WHERE
+ resource = '*'
+ OR role.arn CONTAINS resource
+ OR resource CONTAINS role.name
+ )
+
+ UNWIND nodes(path_principal) as n
+ OPTIONAL MATCH (n)-[pfr]-(pf:{PROWLER_FINDING_LABEL} {{status: 'FAIL', provider_uid: $provider_uid}})
+
+ RETURN path_principal,
+ collect(DISTINCT pf) as dpf, collect(DISTINCT pfr) as dpfr
+ """,
+ parameters=[],
+)
+
+# IAM-006
+AWS_IAM_PRIVESC_UPDATE_LOGIN_PROFILE = AttackPathsQueryDefinition(
+ id="aws-iam-privesc-update-login-profile",
+ name="Console Password Override for Lateral Movement (IAM-006)",
+ short_description="Change the console password of other IAM users to log in as them and gain their permissions.",
+ description="Detect principals who can update console login profiles for other IAM users. By resetting a target user's password, the attacker gains AWS Console access with that user's permissions. Unlike IAM-004, this targets users who already have a login profile configured.",
+ attribution=AttackPathsQueryAttribution(
+ text="pathfinding.cloud - IAM-006 - iam:UpdateLoginProfile",
+ link="https://pathfinding.cloud/paths/iam-006",
+ ),
+ provider="aws",
+ cypher=f"""
+ // Find principals with iam:UpdateLoginProfile permission
+ MATCH path_principal = (aws:AWSAccount {{id: $provider_uid}})--(principal:AWSPrincipal)--(policy:AWSPolicy)--(stmt:AWSPolicyStatement)
+ WHERE stmt.effect = 'Allow'
+ AND any(action IN stmt.action WHERE
+ toLower(action) = 'iam:updateloginprofile'
+ OR toLower(action) = 'iam:*'
+ OR action = '*'
+ )
+
+ // Find target users that the principal can update login profiles for
+ MATCH path_target = (aws)--(target_user:AWSUser)
+ WHERE any(resource IN stmt.resource WHERE
+ resource = '*'
+ OR target_user.arn CONTAINS resource
+ OR resource CONTAINS target_user.name
+ )
+
+ UNWIND nodes(path_principal) + nodes(path_target) as n
+ OPTIONAL MATCH (n)-[pfr]-(pf:{PROWLER_FINDING_LABEL} {{status: 'FAIL', provider_uid: $provider_uid}})
+
+ RETURN path_principal, path_target,
+ collect(DISTINCT pf) as dpf, collect(DISTINCT pfr) as dpfr
+ """,
+ parameters=[],
+)
+
+# IAM-007
+AWS_IAM_PRIVESC_PUT_USER_POLICY = AttackPathsQueryDefinition(
+ id="aws-iam-privesc-put-user-policy",
+ name="Inline Policy Injection on User for Self-Escalation (IAM-007)",
+ short_description="Attach an inline policy with administrative permissions to your own IAM user, instantly escalating privileges.",
+ description="Detect IAM users that can use iam:PutUserPolicy on themselves. A user with this permission can attach an inline policy granting any permissions, including full administrative access, without needing to modify or assume any other resource. This is the user equivalent of IAM-005 (PutRolePolicy).",
+ attribution=AttackPathsQueryAttribution(
+ text="pathfinding.cloud - IAM-007 - iam:PutUserPolicy",
+ link="https://pathfinding.cloud/paths/iam-007",
+ ),
+ provider="aws",
+ cypher=f"""
+ // Find users with iam:PutUserPolicy permission scoped to themselves
+ MATCH path_principal = (aws:AWSAccount {{id: $provider_uid}})--(user:AWSUser)--(policy:AWSPolicy)--(stmt:AWSPolicyStatement)
+ WHERE stmt.effect = 'Allow'
+ AND any(action IN stmt.action WHERE
+ toLower(action) = 'iam:putuserpolicy'
+ OR toLower(action) = 'iam:*'
+ OR action = '*'
+ )
+ AND any(resource IN stmt.resource WHERE
+ resource = '*'
+ OR user.arn CONTAINS resource
+ OR resource CONTAINS user.name
+ )
+
+ UNWIND nodes(path_principal) as n
+ OPTIONAL MATCH (n)-[pfr]-(pf:{PROWLER_FINDING_LABEL} {{status: 'FAIL', provider_uid: $provider_uid}})
+
+ RETURN path_principal,
+ collect(DISTINCT pf) as dpf, collect(DISTINCT pfr) as dpfr
+ """,
+ parameters=[],
+)
+
+# IAM-008
+AWS_IAM_PRIVESC_ATTACH_USER_POLICY = AttackPathsQueryDefinition(
+ id="aws-iam-privesc-attach-user-policy",
+ name="Managed Policy Attachment on User for Self-Escalation (IAM-008)",
+ short_description="Attach existing managed policies with administrative permissions to your own IAM user, instantly escalating privileges.",
+ description="Detect IAM users that can use iam:AttachUserPolicy on themselves. A user with this permission can attach any existing managed policy, including AdministratorAccess, to themselves without needing to modify or assume any other resource. Unlike IAM-007 (PutUserPolicy), this requires an existing managed policy with elevated permissions.",
+ attribution=AttackPathsQueryAttribution(
+ text="pathfinding.cloud - IAM-008 - iam:AttachUserPolicy",
+ link="https://pathfinding.cloud/paths/iam-008",
+ ),
+ provider="aws",
+ cypher=f"""
+ // Find users with iam:AttachUserPolicy permission scoped to themselves
+ MATCH path_principal = (aws:AWSAccount {{id: $provider_uid}})--(user:AWSUser)--(policy:AWSPolicy)--(stmt:AWSPolicyStatement)
+ WHERE stmt.effect = 'Allow'
+ AND any(action IN stmt.action WHERE
+ toLower(action) = 'iam:attachuserpolicy'
+ OR toLower(action) = 'iam:*'
+ OR action = '*'
+ )
+ AND any(resource IN stmt.resource WHERE
+ resource = '*'
+ OR user.arn CONTAINS resource
+ OR resource CONTAINS user.name
+ )
+
+ UNWIND nodes(path_principal) as n
+ OPTIONAL MATCH (n)-[pfr]-(pf:{PROWLER_FINDING_LABEL} {{status: 'FAIL', provider_uid: $provider_uid}})
+
+ RETURN path_principal,
+ collect(DISTINCT pf) as dpf, collect(DISTINCT pfr) as dpfr
+ """,
+ parameters=[],
+)
+
+# IAM-009
+AWS_IAM_PRIVESC_ATTACH_ROLE_POLICY = AttackPathsQueryDefinition(
+ id="aws-iam-privesc-attach-role-policy",
+ name="Managed Policy Attachment on Role for Self-Escalation (IAM-009)",
+ short_description="Attach existing managed policies with administrative permissions to your own IAM role, instantly escalating privileges.",
+ description="Detect IAM roles that can use iam:AttachRolePolicy on themselves. A role with this permission can attach any existing managed policy, including AdministratorAccess, to itself without needing to modify or assume any other resource. Unlike IAM-005 (PutRolePolicy), this requires an existing managed policy with elevated permissions.",
+ attribution=AttackPathsQueryAttribution(
+ text="pathfinding.cloud - IAM-009 - iam:AttachRolePolicy",
+ link="https://pathfinding.cloud/paths/iam-009",
+ ),
+ provider="aws",
+ cypher=f"""
+ // Find roles with iam:AttachRolePolicy permission scoped to themselves
+ MATCH path_principal = (aws:AWSAccount {{id: $provider_uid}})--(role:AWSRole)--(policy:AWSPolicy)--(stmt:AWSPolicyStatement)
+ WHERE stmt.effect = 'Allow'
+ AND any(action IN stmt.action WHERE
+ toLower(action) = 'iam:attachrolepolicy'
+ OR toLower(action) = 'iam:*'
+ OR action = '*'
+ )
+ AND any(resource IN stmt.resource WHERE
+ resource = '*'
+ OR role.arn CONTAINS resource
+ OR resource CONTAINS role.name
+ )
+
+ UNWIND nodes(path_principal) as n
+ OPTIONAL MATCH (n)-[pfr]-(pf:{PROWLER_FINDING_LABEL} {{status: 'FAIL', provider_uid: $provider_uid}})
+
+ RETURN path_principal,
+ collect(DISTINCT pf) as dpf, collect(DISTINCT pfr) as dpfr
+ """,
+ parameters=[],
+)
+
+# IAM-010
+AWS_IAM_PRIVESC_ATTACH_GROUP_POLICY = AttackPathsQueryDefinition(
+ id="aws-iam-privesc-attach-group-policy",
+ name="Managed Policy Attachment on Group for Self-Escalation (IAM-010)",
+ short_description="Attach existing managed policies with administrative permissions to a group you belong to, escalating privileges for all group members.",
+ description="Detect IAM users that can use iam:AttachGroupPolicy on a group they are a member of. A user with this permission can attach any existing managed policy, including AdministratorAccess, to a group they belong to, immediately escalating privileges for all group members.",
+ attribution=AttackPathsQueryAttribution(
+ text="pathfinding.cloud - IAM-010 - iam:AttachGroupPolicy",
+ link="https://pathfinding.cloud/paths/iam-010",
+ ),
+ provider="aws",
+ cypher=f"""
+ // Find users with iam:AttachGroupPolicy permission
+ MATCH path_principal = (aws:AWSAccount {{id: $provider_uid}})--(user:AWSUser)--(policy:AWSPolicy)--(stmt:AWSPolicyStatement)
+ WHERE stmt.effect = 'Allow'
+ AND any(action IN stmt.action WHERE
+ toLower(action) = 'iam:attachgrouppolicy'
+ OR toLower(action) = 'iam:*'
+ OR action = '*'
+ )
+
+ // Find groups the user is a member of and can attach policies to
+ MATCH path_target = (aws)-[:RESOURCE]->(target_group:AWSGroup)<-[:MEMBER_AWS_GROUP]-(user)
+ WHERE any(resource IN stmt.resource WHERE
+ resource = '*'
+ OR target_group.arn CONTAINS resource
+ OR resource CONTAINS target_group.name
+ )
+
+ UNWIND nodes(path_principal) + nodes(path_target) as n
+ OPTIONAL MATCH (n)-[pfr]-(pf:{PROWLER_FINDING_LABEL} {{status: 'FAIL', provider_uid: $provider_uid}})
+
+ RETURN path_principal, path_target,
+ collect(DISTINCT pf) as dpf, collect(DISTINCT pfr) as dpfr
+ """,
+ parameters=[],
+)
+
+# IAM-011
+AWS_IAM_PRIVESC_PUT_GROUP_POLICY = AttackPathsQueryDefinition(
+ id="aws-iam-privesc-put-group-policy",
+ name="Inline Policy Injection on Group for Self-Escalation (IAM-011)",
+ short_description="Attach an inline policy with administrative permissions to a group you belong to, escalating privileges for all group members.",
+ description="Detect IAM users that can use iam:PutGroupPolicy on a group they are a member of. A user with this permission can attach an inline policy granting any permissions to a group they belong to, immediately escalating privileges for all group members. Unlike IAM-010, this does not require an existing managed policy.",
+ attribution=AttackPathsQueryAttribution(
+ text="pathfinding.cloud - IAM-011 - iam:PutGroupPolicy",
+ link="https://pathfinding.cloud/paths/iam-011",
+ ),
+ provider="aws",
+ cypher=f"""
+ // Find users with iam:PutGroupPolicy permission
+ MATCH path_principal = (aws:AWSAccount {{id: $provider_uid}})--(user:AWSUser)--(policy:AWSPolicy)--(stmt:AWSPolicyStatement)
+ WHERE stmt.effect = 'Allow'
+ AND any(action IN stmt.action WHERE
+ toLower(action) = 'iam:putgrouppolicy'
+ OR toLower(action) = 'iam:*'
+ OR action = '*'
+ )
+
+ // Find groups the user is a member of and can put policies on
+ MATCH path_target = (aws)-[:RESOURCE]->(target_group:AWSGroup)<-[:MEMBER_AWS_GROUP]-(user)
+ WHERE any(resource IN stmt.resource WHERE
+ resource = '*'
+ OR target_group.arn CONTAINS resource
+ OR resource CONTAINS target_group.name
+ )
+
+ UNWIND nodes(path_principal) + nodes(path_target) as n
+ OPTIONAL MATCH (n)-[pfr]-(pf:{PROWLER_FINDING_LABEL} {{status: 'FAIL', provider_uid: $provider_uid}})
+
+ RETURN path_principal, path_target,
+ collect(DISTINCT pf) as dpf, collect(DISTINCT pfr) as dpfr
+ """,
+ parameters=[],
+)
+
+# IAM-012
+AWS_IAM_PRIVESC_UPDATE_ASSUME_ROLE_POLICY = AttackPathsQueryDefinition(
+ id="aws-iam-privesc-update-assume-role-policy",
+ name="Trust Policy Hijacking for Role Assumption (IAM-012)",
+ short_description="Modify a role's trust policy to allow yourself to assume it, gaining the role's permissions.",
+ description="Detect principals who can update the assume role policy (trust policy) of other IAM roles. By modifying a target role's trust policy to trust the attacker's principal, the attacker can then assume the role and gain all its permissions, including potential administrative access.",
+ attribution=AttackPathsQueryAttribution(
+ text="pathfinding.cloud - IAM-012 - iam:UpdateAssumeRolePolicy",
+ link="https://pathfinding.cloud/paths/iam-012",
+ ),
+ provider="aws",
+ cypher=f"""
+ // Find principals with iam:UpdateAssumeRolePolicy permission
+ MATCH path_principal = (aws:AWSAccount {{id: $provider_uid}})--(principal:AWSPrincipal)--(policy:AWSPolicy)--(stmt:AWSPolicyStatement)
+ WHERE stmt.effect = 'Allow'
+ AND any(action IN stmt.action WHERE
+ toLower(action) = 'iam:updateassumerolepolicy'
+ OR toLower(action) = 'iam:*'
+ OR action = '*'
+ )
+
+ // Find target roles whose trust policy can be modified
+ MATCH path_target = (aws)--(target_role:AWSRole)
+ WHERE any(resource IN stmt.resource WHERE
+ resource = '*'
+ OR target_role.arn CONTAINS resource
+ OR resource CONTAINS target_role.name
+ )
+
+ UNWIND nodes(path_principal) + nodes(path_target) as n
+ OPTIONAL MATCH (n)-[pfr]-(pf:{PROWLER_FINDING_LABEL} {{status: 'FAIL', provider_uid: $provider_uid}})
+
+ RETURN path_principal, path_target,
+ collect(DISTINCT pf) as dpf, collect(DISTINCT pfr) as dpfr
+ """,
+ parameters=[],
+)
+
+# IAM-013
+AWS_IAM_PRIVESC_ADD_USER_TO_GROUP = AttackPathsQueryDefinition(
+ id="aws-iam-privesc-add-user-to-group",
+ name="Group Membership Hijacking for Privilege Escalation (IAM-013)",
+ short_description="Add yourself to a privileged IAM group to inherit its permissions, gaining access to all policies attached to the group.",
+ description="Detect principals who can add users to IAM groups. By adding themselves to a group with elevated permissions such as AdministratorAccess, the attacker immediately inherits all policies attached to that group. The level of access gained depends on the permissions of the target group.",
+ attribution=AttackPathsQueryAttribution(
+ text="pathfinding.cloud - IAM-013 - iam:AddUserToGroup",
+ link="https://pathfinding.cloud/paths/iam-013",
+ ),
+ provider="aws",
+ cypher=f"""
+ // Find principals with iam:AddUserToGroup permission
+ MATCH path_principal = (aws:AWSAccount {{id: $provider_uid}})--(principal:AWSPrincipal)--(policy:AWSPolicy)--(stmt:AWSPolicyStatement)
+ WHERE stmt.effect = 'Allow'
+ AND any(action IN stmt.action WHERE
+ toLower(action) = 'iam:addusertogroup'
+ OR toLower(action) = 'iam:*'
+ OR action = '*'
+ )
+
+ // Find target groups the principal can add users to
+ MATCH path_target = (aws)-[:RESOURCE]->(target_group:AWSGroup)
+ WHERE any(resource IN stmt.resource WHERE
+ resource = '*'
+ OR target_group.arn CONTAINS resource
+ OR resource CONTAINS target_group.name
+ )
+
+ UNWIND nodes(path_principal) + nodes(path_target) as n
+ OPTIONAL MATCH (n)-[pfr]-(pf:{PROWLER_FINDING_LABEL} {{status: 'FAIL', provider_uid: $provider_uid}})
+
+ RETURN path_principal, path_target,
+ collect(DISTINCT pf) as dpf, collect(DISTINCT pfr) as dpfr
+ """,
+ parameters=[],
+)
+
+# IAM-014
+AWS_IAM_PRIVESC_ATTACH_ROLE_POLICY_ASSUME_ROLE = AttackPathsQueryDefinition(
+ id="aws-iam-privesc-attach-role-policy-assume-role",
+ name="Managed Policy Attachment with Role Assumption for Lateral Movement (IAM-014)",
+ short_description="Attach administrative managed policies to another role you can assume, then assume it to gain elevated privileges.",
+ description="Detect principals who can attach managed policies to a different IAM role and also assume that role. By attaching AdministratorAccess to a target role and then assuming it, the attacker gains full administrative access. This is a variation of IAM-009 for lateral movement where the principal targets another assumable role instead of their own.",
+ attribution=AttackPathsQueryAttribution(
+ text="pathfinding.cloud - IAM-014 - iam:AttachRolePolicy + sts:AssumeRole",
+ link="https://pathfinding.cloud/paths/iam-014",
+ ),
+ provider="aws",
+ cypher=f"""
+ // Find principals with iam:AttachRolePolicy permission
+ MATCH path_principal = (aws:AWSAccount {{id: $provider_uid}})--(principal:AWSPrincipal)--(policy:AWSPolicy)--(stmt:AWSPolicyStatement)
+ WHERE stmt.effect = 'Allow'
+ AND any(action IN stmt.action WHERE
toLower(action) = 'iam:attachrolepolicy'
OR toLower(action) = 'iam:*'
OR action = '*'
)
- // Find statements granting sts:AssumeRole
- MATCH path_assume = (principal)--(assume_policy:AWSPolicy)--(stmt_assume:AWSPolicyStatement)
- WHERE stmt_assume.effect = 'Allow'
- AND any(action IN stmt_assume.action WHERE
+ // Find target roles the principal can assume and attach policies to
+ MATCH path_target = (aws)--(target_role:AWSRole)<-[:STS_ASSUMEROLE_ALLOW]-(principal)
+ WHERE any(resource IN stmt.resource WHERE
+ resource = '*'
+ OR target_role.arn CONTAINS resource
+ OR resource CONTAINS target_role.name
+ )
+
+ UNWIND nodes(path_principal) + nodes(path_target) as n
+ OPTIONAL MATCH (n)-[pfr]-(pf:{PROWLER_FINDING_LABEL} {{status: 'FAIL', provider_uid: $provider_uid}})
+
+ RETURN path_principal, path_target,
+ collect(DISTINCT pf) as dpf, collect(DISTINCT pfr) as dpfr
+ """,
+ parameters=[],
+)
+
+# IAM-015
+AWS_IAM_PRIVESC_ATTACH_USER_POLICY_CREATE_ACCESS_KEY = AttackPathsQueryDefinition(
+ id="aws-iam-privesc-attach-user-policy-create-access-key",
+ name="Managed Policy Attachment with Access Key Creation for Lateral Movement (IAM-015)",
+ short_description="Attach administrative managed policies to another IAM user and create access keys for them to gain programmatic access with elevated privileges.",
+ description="Detect principals who can attach managed policies to another IAM user and also create access keys for that user. By attaching AdministratorAccess to a target user and creating access keys, the attacker gains programmatic access with the target user's elevated permissions. This combines IAM-008 (AttachUserPolicy) with IAM-002 (CreateAccessKey) for lateral movement.",
+ attribution=AttackPathsQueryAttribution(
+ text="pathfinding.cloud - IAM-015 - iam:AttachUserPolicy + iam:CreateAccessKey",
+ link="https://pathfinding.cloud/paths/iam-015",
+ ),
+ provider="aws",
+ cypher=f"""
+ // Find principals with iam:AttachUserPolicy permission
+ MATCH path_principal = (aws:AWSAccount {{id: $provider_uid}})--(principal:AWSPrincipal)--(policy:AWSPolicy)--(stmt:AWSPolicyStatement)
+ WHERE stmt.effect = 'Allow'
+ AND any(action IN stmt.action WHERE
+ toLower(action) = 'iam:attachuserpolicy'
+ OR toLower(action) = 'iam:*'
+ OR action = '*'
+ )
+
+ // Find iam:CreateAccessKey permission
+ MATCH (principal)--(policy2:AWSPolicy)--(stmt2:AWSPolicyStatement)
+ WHERE stmt2.effect = 'Allow'
+ AND any(action IN stmt2.action WHERE
+ toLower(action) = 'iam:createaccesskey'
+ OR toLower(action) = 'iam:*'
+ OR action = '*'
+ )
+
+ // Find target users the principal can attach policies to and create keys for
+ MATCH path_target = (aws)--(target_user:AWSUser)
+ WHERE any(resource IN stmt.resource WHERE
+ resource = '*'
+ OR target_user.arn CONTAINS resource
+ OR resource CONTAINS target_user.name
+ )
+ AND any(resource IN stmt2.resource WHERE
+ resource = '*'
+ OR target_user.arn CONTAINS resource
+ OR resource CONTAINS target_user.name
+ )
+
+ UNWIND nodes(path_principal) + nodes(path_target) as n
+ OPTIONAL MATCH (n)-[pfr]-(pf:{PROWLER_FINDING_LABEL} {{status: 'FAIL', provider_uid: $provider_uid}})
+
+ RETURN path_principal, path_target,
+ collect(DISTINCT pf) as dpf, collect(DISTINCT pfr) as dpfr
+ """,
+ parameters=[],
+)
+
+# IAM-016
+AWS_IAM_PRIVESC_CREATE_POLICY_VERSION_ASSUME_ROLE = AttackPathsQueryDefinition(
+ id="aws-iam-privesc-create-policy-version-assume-role",
+ name="Policy Version Override with Role Assumption for Lateral Movement (IAM-016)",
+ short_description="Create a new version of a customer-managed policy attached to another role with administrative permissions, then assume that role to gain elevated access.",
+ description="Detect principals who can create new versions of customer-managed policies attached to other roles and also assume those roles. By creating a new policy version with administrative permissions on a policy attached to a target role, then assuming that role, the attacker gains full administrative access. This is a variation of IAM-001 for lateral movement where the modified policy is attached to an assumable role rather than the attacker's own principal.",
+ attribution=AttackPathsQueryAttribution(
+ text="pathfinding.cloud - IAM-016 - iam:CreatePolicyVersion + sts:AssumeRole",
+ link="https://pathfinding.cloud/paths/iam-016",
+ ),
+ provider="aws",
+ cypher=f"""
+ // Find principals with iam:CreatePolicyVersion permission
+ MATCH path_principal = (aws:AWSAccount {{id: $provider_uid}})--(principal:AWSPrincipal)--(policy:AWSPolicy)--(stmt:AWSPolicyStatement)
+ WHERE stmt.effect = 'Allow'
+ AND any(action IN stmt.action WHERE
+ toLower(action) = 'iam:createpolicyversion'
+ OR toLower(action) = 'iam:*'
+ OR action = '*'
+ )
+
+ // Find target roles the principal can assume that have customer-managed policies the principal can modify
+ MATCH path_target = (aws)--(target_role:AWSRole)<-[:STS_ASSUMEROLE_ALLOW]-(principal)
+ MATCH (target_role)--(target_policy:AWSPolicy)
+ WHERE target_policy.arn CONTAINS $provider_uid
+ AND any(resource IN stmt.resource WHERE
+ resource = '*'
+ OR target_policy.arn CONTAINS resource
+ )
+
+ UNWIND nodes(path_principal) + nodes(path_target) as n
+ OPTIONAL MATCH (n)-[pfr]-(pf:{PROWLER_FINDING_LABEL} {{status: 'FAIL', provider_uid: $provider_uid}})
+
+ RETURN path_principal, path_target,
+ collect(DISTINCT pf) as dpf, collect(DISTINCT pfr) as dpfr
+ """,
+ parameters=[],
+)
+
+# IAM-017
+AWS_IAM_PRIVESC_PUT_ROLE_POLICY_ASSUME_ROLE = AttackPathsQueryDefinition(
+ id="aws-iam-privesc-put-role-policy-assume-role",
+ name="Inline Policy Injection with Role Assumption for Lateral Movement (IAM-017)",
+ short_description="Attach an inline policy with administrative permissions to another role you can assume, then assume it to gain elevated privileges.",
+ description="Detect principals who can add inline policies to a different IAM role and also assume that role. By adding an inline policy granting administrative permissions to a target role and then assuming it, the attacker gains full administrative access. This is a variation of IAM-005 for lateral movement where the principal targets another assumable role instead of their own.",
+ attribution=AttackPathsQueryAttribution(
+ text="pathfinding.cloud - IAM-017 - iam:PutRolePolicy + sts:AssumeRole",
+ link="https://pathfinding.cloud/paths/iam-017",
+ ),
+ provider="aws",
+ cypher=f"""
+ // Find principals with iam:PutRolePolicy permission
+ MATCH path_principal = (aws:AWSAccount {{id: $provider_uid}})--(principal:AWSPrincipal)--(policy:AWSPolicy)--(stmt:AWSPolicyStatement)
+ WHERE stmt.effect = 'Allow'
+ AND any(action IN stmt.action WHERE
+ toLower(action) = 'iam:putrolepolicy'
+ OR toLower(action) = 'iam:*'
+ OR action = '*'
+ )
+
+ // Find target roles the principal can assume and put inline policies on
+ MATCH path_target = (aws)--(target_role:AWSRole)<-[:STS_ASSUMEROLE_ALLOW]-(principal)
+ WHERE any(resource IN stmt.resource WHERE
+ resource = '*'
+ OR target_role.arn CONTAINS resource
+ OR resource CONTAINS target_role.name
+ )
+
+ UNWIND nodes(path_principal) + nodes(path_target) as n
+ OPTIONAL MATCH (n)-[pfr]-(pf:{PROWLER_FINDING_LABEL} {{status: 'FAIL', provider_uid: $provider_uid}})
+
+ RETURN path_principal, path_target,
+ collect(DISTINCT pf) as dpf, collect(DISTINCT pfr) as dpfr
+ """,
+ parameters=[],
+)
+
+# IAM-018
+AWS_IAM_PRIVESC_PUT_USER_POLICY_CREATE_ACCESS_KEY = AttackPathsQueryDefinition(
+ id="aws-iam-privesc-put-user-policy-create-access-key",
+ name="Inline Policy Injection with Access Key Creation for Lateral Movement (IAM-018)",
+ short_description="Attach an inline policy with administrative permissions to another IAM user and create access keys for them to gain programmatic access with elevated privileges.",
+ description="Detect principals who can add inline policies to another IAM user and also create access keys for that user. By adding an administrative inline policy to a target user and creating access keys, the attacker gains programmatic access with the target user's elevated permissions. This combines IAM-007 (PutUserPolicy) with IAM-002 (CreateAccessKey) for lateral movement.",
+ attribution=AttackPathsQueryAttribution(
+ text="pathfinding.cloud - IAM-018 - iam:PutUserPolicy + iam:CreateAccessKey",
+ link="https://pathfinding.cloud/paths/iam-018",
+ ),
+ provider="aws",
+ cypher=f"""
+ // Find principals with iam:PutUserPolicy permission
+ MATCH path_principal = (aws:AWSAccount {{id: $provider_uid}})--(principal:AWSPrincipal)--(policy:AWSPolicy)--(stmt:AWSPolicyStatement)
+ WHERE stmt.effect = 'Allow'
+ AND any(action IN stmt.action WHERE
+ toLower(action) = 'iam:putuserpolicy'
+ OR toLower(action) = 'iam:*'
+ OR action = '*'
+ )
+
+ // Find iam:CreateAccessKey permission
+ MATCH (principal)--(policy2:AWSPolicy)--(stmt2:AWSPolicyStatement)
+ WHERE stmt2.effect = 'Allow'
+ AND any(action IN stmt2.action WHERE
+ toLower(action) = 'iam:createaccesskey'
+ OR toLower(action) = 'iam:*'
+ OR action = '*'
+ )
+
+ // Find target users the principal can put policies on and create keys for
+ MATCH path_target = (aws)--(target_user:AWSUser)
+ WHERE any(resource IN stmt.resource WHERE
+ resource = '*'
+ OR target_user.arn CONTAINS resource
+ OR resource CONTAINS target_user.name
+ )
+ AND any(resource IN stmt2.resource WHERE
+ resource = '*'
+ OR target_user.arn CONTAINS resource
+ OR resource CONTAINS target_user.name
+ )
+
+ UNWIND nodes(path_principal) + nodes(path_target) as n
+ OPTIONAL MATCH (n)-[pfr]-(pf:{PROWLER_FINDING_LABEL} {{status: 'FAIL', provider_uid: $provider_uid}})
+
+ RETURN path_principal, path_target,
+ collect(DISTINCT pf) as dpf, collect(DISTINCT pfr) as dpfr
+ """,
+ parameters=[],
+)
+
+# IAM-019
+AWS_IAM_PRIVESC_ATTACH_ROLE_POLICY_UPDATE_ASSUME_ROLE = AttackPathsQueryDefinition(
+ id="aws-iam-privesc-attach-role-policy-update-assume-role",
+ name="Managed Policy Attachment with Trust Policy Hijacking for Privilege Escalation (IAM-019)",
+ short_description="Attach administrative managed policies to a role and modify its trust policy to allow yourself to assume it, gaining elevated privileges without prior assume-role access.",
+ description="Detect principals who can attach managed policies to an IAM role and also update that role's trust policy. By attaching AdministratorAccess and modifying the trust policy to allow the attacker, the principal can then assume the role without needing pre-existing sts:AssumeRole permission. This combines IAM-009 (AttachRolePolicy) with IAM-012 (UpdateAssumeRolePolicy).",
+ attribution=AttackPathsQueryAttribution(
+ text="pathfinding.cloud - IAM-019 - iam:AttachRolePolicy + iam:UpdateAssumeRolePolicy",
+ link="https://pathfinding.cloud/paths/iam-019",
+ ),
+ provider="aws",
+ cypher=f"""
+ // Find principals with iam:AttachRolePolicy permission
+ MATCH path_principal = (aws:AWSAccount {{id: $provider_uid}})--(principal:AWSPrincipal)--(policy:AWSPolicy)--(stmt:AWSPolicyStatement)
+ WHERE stmt.effect = 'Allow'
+ AND any(action IN stmt.action WHERE
+ toLower(action) = 'iam:attachrolepolicy'
+ OR toLower(action) = 'iam:*'
+ OR action = '*'
+ )
+
+ // Find iam:UpdateAssumeRolePolicy permission
+ MATCH (principal)--(policy2:AWSPolicy)--(stmt2:AWSPolicyStatement)
+ WHERE stmt2.effect = 'Allow'
+ AND any(action IN stmt2.action WHERE
+ toLower(action) = 'iam:updateassumerolepolicy'
+ OR toLower(action) = 'iam:*'
+ OR action = '*'
+ )
+
+ // Find target roles the principal can attach policies to and update trust policy for
+ MATCH path_target = (aws)--(target_role:AWSRole)
+ WHERE any(resource IN stmt.resource WHERE
+ resource = '*'
+ OR target_role.arn CONTAINS resource
+ OR resource CONTAINS target_role.name
+ )
+ AND any(resource IN stmt2.resource WHERE
+ resource = '*'
+ OR target_role.arn CONTAINS resource
+ OR resource CONTAINS target_role.name
+ )
+
+ UNWIND nodes(path_principal) + nodes(path_target) as n
+ OPTIONAL MATCH (n)-[pfr]-(pf:{PROWLER_FINDING_LABEL} {{status: 'FAIL', provider_uid: $provider_uid}})
+
+ RETURN path_principal, path_target,
+ collect(DISTINCT pf) as dpf, collect(DISTINCT pfr) as dpfr
+ """,
+ parameters=[],
+)
+
+# IAM-020
+AWS_IAM_PRIVESC_CREATE_POLICY_VERSION_UPDATE_ASSUME_ROLE = AttackPathsQueryDefinition(
+ id="aws-iam-privesc-create-policy-version-update-assume-role",
+ name="Policy Version Override with Trust Policy Hijacking for Privilege Escalation (IAM-020)",
+ short_description="Create a new version of a customer-managed policy attached to a role with administrative permissions and modify its trust policy to assume it, without prior assume-role access.",
+ description="Detect principals who can create new versions of customer-managed policies attached to roles and also update those roles' trust policies. By creating an administrative policy version and modifying the trust policy to allow the attacker, the principal can assume the role without needing pre-existing sts:AssumeRole permission. This combines IAM-001 (CreatePolicyVersion) with IAM-012 (UpdateAssumeRolePolicy).",
+ attribution=AttackPathsQueryAttribution(
+ text="pathfinding.cloud - IAM-020 - iam:CreatePolicyVersion + iam:UpdateAssumeRolePolicy",
+ link="https://pathfinding.cloud/paths/iam-020",
+ ),
+ provider="aws",
+ cypher=f"""
+ // Find principals with iam:CreatePolicyVersion permission
+ MATCH path_principal = (aws:AWSAccount {{id: $provider_uid}})--(principal:AWSPrincipal)--(policy:AWSPolicy)--(stmt:AWSPolicyStatement)
+ WHERE stmt.effect = 'Allow'
+ AND any(action IN stmt.action WHERE
+ toLower(action) = 'iam:createpolicyversion'
+ OR toLower(action) = 'iam:*'
+ OR action = '*'
+ )
+
+ // Find iam:UpdateAssumeRolePolicy permission
+ MATCH (principal)--(policy2:AWSPolicy)--(stmt2:AWSPolicyStatement)
+ WHERE stmt2.effect = 'Allow'
+ AND any(action IN stmt2.action WHERE
+ toLower(action) = 'iam:updateassumerolepolicy'
+ OR toLower(action) = 'iam:*'
+ OR action = '*'
+ )
+
+ // Find target roles with customer-managed policies the principal can modify and update trust policy for
+ MATCH path_target = (aws)--(target_role:AWSRole)
+ WHERE any(resource IN stmt2.resource WHERE
+ resource = '*'
+ OR target_role.arn CONTAINS resource
+ OR resource CONTAINS target_role.name
+ )
+ MATCH (target_role)--(target_policy:AWSPolicy)
+ WHERE target_policy.arn CONTAINS $provider_uid
+ AND any(resource IN stmt.resource WHERE
+ resource = '*'
+ OR target_policy.arn CONTAINS resource
+ )
+
+ UNWIND nodes(path_principal) + nodes(path_target) as n
+ OPTIONAL MATCH (n)-[pfr]-(pf:{PROWLER_FINDING_LABEL} {{status: 'FAIL', provider_uid: $provider_uid}})
+
+ RETURN path_principal, path_target,
+ collect(DISTINCT pf) as dpf, collect(DISTINCT pfr) as dpfr
+ """,
+ parameters=[],
+)
+
+# IAM-021
+AWS_IAM_PRIVESC_PUT_ROLE_POLICY_UPDATE_ASSUME_ROLE = AttackPathsQueryDefinition(
+ id="aws-iam-privesc-put-role-policy-update-assume-role",
+ name="Inline Policy Injection with Trust Policy Hijacking for Privilege Escalation (IAM-021)",
+ short_description="Add an inline policy with administrative permissions to a role and modify its trust policy to allow yourself to assume it, gaining elevated privileges without prior assume-role access.",
+ description="Detect principals who can add inline policies to an IAM role and also update that role's trust policy. By adding an administrative inline policy and modifying the trust policy to allow the attacker, the principal can then assume the role without needing pre-existing sts:AssumeRole permission. This combines IAM-005 (PutRolePolicy) with IAM-012 (UpdateAssumeRolePolicy).",
+ attribution=AttackPathsQueryAttribution(
+ text="pathfinding.cloud - IAM-021 - iam:PutRolePolicy + iam:UpdateAssumeRolePolicy",
+ link="https://pathfinding.cloud/paths/iam-021",
+ ),
+ provider="aws",
+ cypher=f"""
+ // Find principals with iam:PutRolePolicy permission
+ MATCH path_principal = (aws:AWSAccount {{id: $provider_uid}})--(principal:AWSPrincipal)--(policy:AWSPolicy)--(stmt:AWSPolicyStatement)
+ WHERE stmt.effect = 'Allow'
+ AND any(action IN stmt.action WHERE
+ toLower(action) = 'iam:putrolepolicy'
+ OR toLower(action) = 'iam:*'
+ OR action = '*'
+ )
+
+ // Find iam:UpdateAssumeRolePolicy permission
+ MATCH (principal)--(policy2:AWSPolicy)--(stmt2:AWSPolicyStatement)
+ WHERE stmt2.effect = 'Allow'
+ AND any(action IN stmt2.action WHERE
+ toLower(action) = 'iam:updateassumerolepolicy'
+ OR toLower(action) = 'iam:*'
+ OR action = '*'
+ )
+
+ // Find target roles the principal can put inline policies on and update trust policy for
+ MATCH path_target = (aws)--(target_role:AWSRole)
+ WHERE any(resource IN stmt.resource WHERE
+ resource = '*'
+ OR target_role.arn CONTAINS resource
+ OR resource CONTAINS target_role.name
+ )
+ AND any(resource IN stmt2.resource WHERE
+ resource = '*'
+ OR target_role.arn CONTAINS resource
+ OR resource CONTAINS target_role.name
+ )
+
+ UNWIND nodes(path_principal) + nodes(path_target) as n
+ OPTIONAL MATCH (n)-[pfr]-(pf:{PROWLER_FINDING_LABEL} {{status: 'FAIL', provider_uid: $provider_uid}})
+
+ RETURN path_principal, path_target,
+ collect(DISTINCT pf) as dpf, collect(DISTINCT pfr) as dpfr
+ """,
+ parameters=[],
+)
+
+# LAMBDA-001
+AWS_LAMBDA_PRIVESC_PASSROLE_CREATE_FUNCTION = AttackPathsQueryDefinition(
+ id="aws-lambda-privesc-passrole-create-function",
+ name="Lambda Function Creation with Privileged Role (LAMBDA-001)",
+ short_description="Create a Lambda function with a privileged IAM role and invoke it to execute code with that role's permissions.",
+ description="Detect principals who can create Lambda functions with privileged IAM roles and invoke them. By passing a privileged role to a new Lambda function and invoking it, the attacker executes code with the role's permissions, gaining access to any resources the role can access.",
+ attribution=AttackPathsQueryAttribution(
+ text="pathfinding.cloud - LAMBDA-001 - iam:PassRole + lambda:CreateFunction + lambda:InvokeFunction",
+ link="https://pathfinding.cloud/paths/lambda-001",
+ ),
+ provider="aws",
+ cypher=f"""
+ // Find principals with iam:PassRole permission
+ MATCH path_principal = (aws:AWSAccount {{id: $provider_uid}})--(principal:AWSPrincipal)--(passrole_policy:AWSPolicy)--(stmt_passrole:AWSPolicyStatement)
+ WHERE stmt_passrole.effect = 'Allow'
+ AND any(action IN stmt_passrole.action WHERE
+ toLower(action) = 'iam:passrole'
+ OR toLower(action) = 'iam:*'
+ OR action = '*'
+ )
+
+ // Find lambda:CreateFunction permission
+ MATCH (principal)--(create_policy:AWSPolicy)--(stmt_create:AWSPolicyStatement)
+ WHERE stmt_create.effect = 'Allow'
+ AND any(action IN stmt_create.action WHERE
+ toLower(action) = 'lambda:createfunction'
+ OR toLower(action) = 'lambda:*'
+ OR action = '*'
+ )
+
+ // Find lambda:InvokeFunction permission
+ MATCH (principal)--(invoke_policy:AWSPolicy)--(stmt_invoke:AWSPolicyStatement)
+ WHERE stmt_invoke.effect = 'Allow'
+ AND any(action IN stmt_invoke.action WHERE
+ toLower(action) = 'lambda:invokefunction'
+ OR toLower(action) = 'lambda:*'
+ OR action = '*'
+ )
+
+ // Find roles that trust Lambda service (can be passed to Lambda)
+ MATCH path_target = (aws)--(target_role:AWSRole)-[:TRUSTS_AWS_PRINCIPAL]->(:AWSPrincipal {{arn: 'lambda.amazonaws.com'}})
+ WHERE any(resource IN stmt_passrole.resource WHERE
+ resource = '*'
+ OR target_role.arn CONTAINS resource
+ OR resource CONTAINS target_role.name
+ )
+
+ UNWIND nodes(path_principal) + nodes(path_target) as n
+ OPTIONAL MATCH (n)-[pfr]-(pf:{PROWLER_FINDING_LABEL} {{status: 'FAIL', provider_uid: $provider_uid}})
+
+ RETURN path_principal, path_target,
+ collect(DISTINCT pf) as dpf, collect(DISTINCT pfr) as dpfr
+ """,
+ parameters=[],
+)
+
+# LAMBDA-002
+AWS_LAMBDA_PRIVESC_PASSROLE_CREATE_FUNCTION_EVENT_SOURCE = AttackPathsQueryDefinition(
+ id="aws-lambda-privesc-passrole-create-function-event-source",
+ name="Lambda Function Creation with Event Source Trigger (LAMBDA-002)",
+ short_description="Create a Lambda function with a privileged IAM role and an event source mapping to trigger it automatically, executing code with the role's permissions.",
+ description="Detect principals who can create Lambda functions with privileged IAM roles and configure event source mappings to trigger them. By passing a privileged role to a new Lambda function and creating an event source mapping (DynamoDB stream, Kinesis, SQS), the attacker executes code with elevated privileges without needing to invoke the function directly.",
+ attribution=AttackPathsQueryAttribution(
+ text="pathfinding.cloud - LAMBDA-002 - iam:PassRole + lambda:CreateFunction + lambda:CreateEventSourceMapping",
+ link="https://pathfinding.cloud/paths/lambda-002",
+ ),
+ provider="aws",
+ cypher=f"""
+ // Find principals with iam:PassRole permission
+ MATCH path_principal = (aws:AWSAccount {{id: $provider_uid}})--(principal:AWSPrincipal)--(passrole_policy:AWSPolicy)--(stmt_passrole:AWSPolicyStatement)
+ WHERE stmt_passrole.effect = 'Allow'
+ AND any(action IN stmt_passrole.action WHERE
+ toLower(action) = 'iam:passrole'
+ OR toLower(action) = 'iam:*'
+ OR action = '*'
+ )
+
+ // Find lambda:CreateFunction permission
+ MATCH (principal)--(create_policy:AWSPolicy)--(stmt_create:AWSPolicyStatement)
+ WHERE stmt_create.effect = 'Allow'
+ AND any(action IN stmt_create.action WHERE
+ toLower(action) = 'lambda:createfunction'
+ OR toLower(action) = 'lambda:*'
+ OR action = '*'
+ )
+
+ // Find lambda:CreateEventSourceMapping permission
+ MATCH (principal)--(event_policy:AWSPolicy)--(stmt_event:AWSPolicyStatement)
+ WHERE stmt_event.effect = 'Allow'
+ AND any(action IN stmt_event.action WHERE
+ toLower(action) = 'lambda:createeventsourcemapping'
+ OR toLower(action) = 'lambda:*'
+ OR action = '*'
+ )
+
+ // Find roles that trust Lambda service (can be passed to Lambda)
+ MATCH path_target = (aws)--(target_role:AWSRole)-[:TRUSTS_AWS_PRINCIPAL]->(:AWSPrincipal {{arn: 'lambda.amazonaws.com'}})
+ WHERE any(resource IN stmt_passrole.resource WHERE
+ resource = '*'
+ OR target_role.arn CONTAINS resource
+ OR resource CONTAINS target_role.name
+ )
+
+ UNWIND nodes(path_principal) + nodes(path_target) as n
+ OPTIONAL MATCH (n)-[pfr]-(pf:{PROWLER_FINDING_LABEL} {{status: 'FAIL', provider_uid: $provider_uid}})
+
+ RETURN path_principal, path_target,
+ collect(DISTINCT pf) as dpf, collect(DISTINCT pfr) as dpfr
+ """,
+ parameters=[],
+)
+
+# LAMBDA-003
+AWS_LAMBDA_PRIVESC_UPDATE_FUNCTION_CODE = AttackPathsQueryDefinition(
+ id="aws-lambda-privesc-update-function-code",
+ name="Lambda Function Code Injection (LAMBDA-003)",
+ short_description="Modify the code of an existing Lambda function to execute arbitrary commands with the function's execution role permissions.",
+ description="Detect principals who can update the code of existing Lambda functions. By replacing a Lambda function's code with malicious code, the attacker executes arbitrary commands with the privileges of the function's execution role when it is next invoked, either manually or via automatic triggers.",
+ attribution=AttackPathsQueryAttribution(
+ text="pathfinding.cloud - LAMBDA-003 - lambda:UpdateFunctionCode",
+ link="https://pathfinding.cloud/paths/lambda-003",
+ ),
+ provider="aws",
+ cypher=f"""
+ // Find principals with lambda:UpdateFunctionCode permission
+ MATCH path_principal = (aws:AWSAccount {{id: $provider_uid}})--(principal:AWSPrincipal)--(policy:AWSPolicy)--(stmt:AWSPolicyStatement)
+ WHERE stmt.effect = 'Allow'
+ AND any(action IN stmt.action WHERE
+ toLower(action) = 'lambda:updatefunctioncode'
+ OR toLower(action) = 'lambda:*'
+ OR action = '*'
+ )
+
+ // Find existing Lambda functions with execution roles
+ MATCH path_target = (aws)-[:RESOURCE]->(lambda_fn:AWSLambda)-[:STS_ASSUMEROLE_ALLOW]->(target_role:AWSRole)
+ WHERE any(resource IN stmt.resource WHERE
+ resource = '*'
+ OR lambda_fn.arn CONTAINS resource
+ OR resource CONTAINS lambda_fn.name
+ )
+
+ UNWIND nodes(path_principal) + nodes(path_target) as n
+ OPTIONAL MATCH (n)-[pfr]-(pf:{PROWLER_FINDING_LABEL} {{status: 'FAIL', provider_uid: $provider_uid}})
+
+ RETURN path_principal, path_target,
+ collect(DISTINCT pf) as dpf, collect(DISTINCT pfr) as dpfr
+ """,
+ parameters=[],
+)
+
+# LAMBDA-004
+AWS_LAMBDA_PRIVESC_UPDATE_FUNCTION_CODE_INVOKE = AttackPathsQueryDefinition(
+ id="aws-lambda-privesc-update-function-code-invoke",
+ name="Lambda Function Code Injection with Direct Invocation (LAMBDA-004)",
+ short_description="Modify the code of an existing Lambda function and invoke it directly to execute arbitrary commands with the function's execution role permissions.",
+ description="Detect principals who can update the code of existing Lambda functions and invoke them. By replacing a Lambda function's code with malicious code and invoking it directly, the attacker executes arbitrary commands with the privileges of the function's execution role immediately, without waiting for automatic triggers.",
+ attribution=AttackPathsQueryAttribution(
+ text="pathfinding.cloud - LAMBDA-004 - lambda:UpdateFunctionCode + lambda:InvokeFunction",
+ link="https://pathfinding.cloud/paths/lambda-004",
+ ),
+ provider="aws",
+ cypher=f"""
+ // Find principals with lambda:UpdateFunctionCode permission
+ MATCH path_principal = (aws:AWSAccount {{id: $provider_uid}})--(principal:AWSPrincipal)--(policy:AWSPolicy)--(stmt:AWSPolicyStatement)
+ WHERE stmt.effect = 'Allow'
+ AND any(action IN stmt.action WHERE
+ toLower(action) = 'lambda:updatefunctioncode'
+ OR toLower(action) = 'lambda:*'
+ OR action = '*'
+ )
+
+ // Find lambda:InvokeFunction permission
+ MATCH (principal)--(policy2:AWSPolicy)--(stmt2:AWSPolicyStatement)
+ WHERE stmt2.effect = 'Allow'
+ AND any(action IN stmt2.action WHERE
+ toLower(action) = 'lambda:invokefunction'
+ OR toLower(action) = 'lambda:*'
+ OR action = '*'
+ )
+
+ // Find existing Lambda functions with execution roles
+ MATCH path_target = (aws)-[:RESOURCE]->(lambda_fn:AWSLambda)-[:STS_ASSUMEROLE_ALLOW]->(target_role:AWSRole)
+ WHERE any(resource IN stmt.resource WHERE
+ resource = '*'
+ OR lambda_fn.arn CONTAINS resource
+ OR resource CONTAINS lambda_fn.name
+ )
+ AND any(resource IN stmt2.resource WHERE
+ resource = '*'
+ OR lambda_fn.arn CONTAINS resource
+ OR resource CONTAINS lambda_fn.name
+ )
+
+ UNWIND nodes(path_principal) + nodes(path_target) as n
+ OPTIONAL MATCH (n)-[pfr]-(pf:{PROWLER_FINDING_LABEL} {{status: 'FAIL', provider_uid: $provider_uid}})
+
+ RETURN path_principal, path_target,
+ collect(DISTINCT pf) as dpf, collect(DISTINCT pfr) as dpfr
+ """,
+ parameters=[],
+)
+
+# LAMBDA-005
+AWS_LAMBDA_PRIVESC_UPDATE_FUNCTION_CODE_ADD_PERMISSION = AttackPathsQueryDefinition(
+ id="aws-lambda-privesc-update-function-code-add-permission",
+ name="Lambda Function Code Injection with Resource Policy Grant (LAMBDA-005)",
+ short_description="Modify the code of an existing Lambda function and grant yourself invocation permission via its resource-based policy to execute code with the function's execution role.",
+ description="Detect principals who can update the code of existing Lambda functions and add permissions to their resource-based policies. By replacing a Lambda function's code and granting themselves invoke access through the resource-based policy, the attacker executes malicious code with the function's execution role without needing lambda:InvokeFunction as an IAM permission.",
+ attribution=AttackPathsQueryAttribution(
+ text="pathfinding.cloud - LAMBDA-005 - lambda:UpdateFunctionCode + lambda:AddPermission",
+ link="https://pathfinding.cloud/paths/lambda-005",
+ ),
+ provider="aws",
+ cypher=f"""
+ // Find principals with lambda:UpdateFunctionCode permission
+ MATCH path_principal = (aws:AWSAccount {{id: $provider_uid}})--(principal:AWSPrincipal)--(policy:AWSPolicy)--(stmt:AWSPolicyStatement)
+ WHERE stmt.effect = 'Allow'
+ AND any(action IN stmt.action WHERE
+ toLower(action) = 'lambda:updatefunctioncode'
+ OR toLower(action) = 'lambda:*'
+ OR action = '*'
+ )
+
+ // Find lambda:AddPermission permission
+ MATCH (principal)--(policy2:AWSPolicy)--(stmt2:AWSPolicyStatement)
+ WHERE stmt2.effect = 'Allow'
+ AND any(action IN stmt2.action WHERE
+ toLower(action) = 'lambda:addpermission'
+ OR toLower(action) = 'lambda:*'
+ OR action = '*'
+ )
+
+ // Find existing Lambda functions with execution roles
+ MATCH path_target = (aws)-[:RESOURCE]->(lambda_fn:AWSLambda)-[:STS_ASSUMEROLE_ALLOW]->(target_role:AWSRole)
+ WHERE any(resource IN stmt.resource WHERE
+ resource = '*'
+ OR lambda_fn.arn CONTAINS resource
+ OR resource CONTAINS lambda_fn.name
+ )
+ AND any(resource IN stmt2.resource WHERE
+ resource = '*'
+ OR lambda_fn.arn CONTAINS resource
+ OR resource CONTAINS lambda_fn.name
+ )
+
+ UNWIND nodes(path_principal) + nodes(path_target) as n
+ OPTIONAL MATCH (n)-[pfr]-(pf:{PROWLER_FINDING_LABEL} {{status: 'FAIL', provider_uid: $provider_uid}})
+
+ RETURN path_principal, path_target,
+ collect(DISTINCT pf) as dpf, collect(DISTINCT pfr) as dpfr
+ """,
+ parameters=[],
+)
+
+# LAMBDA-006
+AWS_LAMBDA_PRIVESC_PASSROLE_CREATE_FUNCTION_ADD_PERMISSION = AttackPathsQueryDefinition(
+ id="aws-lambda-privesc-passrole-create-function-add-permission",
+ name="Lambda Function Creation with Resource Policy Invocation (LAMBDA-006)",
+ short_description="Create a Lambda function with a privileged IAM role and grant yourself invocation permission via its resource-based policy to execute code with the role's permissions.",
+ description="Detect principals who can create Lambda functions with privileged IAM roles and add permissions to their resource-based policies. By passing a privileged role to a new Lambda function and granting themselves invoke access through the resource-based policy, the attacker executes malicious code with elevated privileges without needing lambda:InvokeFunction as an IAM permission.",
+ attribution=AttackPathsQueryAttribution(
+ text="pathfinding.cloud - LAMBDA-006 - iam:PassRole + lambda:CreateFunction + lambda:AddPermission",
+ link="https://pathfinding.cloud/paths/lambda-006",
+ ),
+ provider="aws",
+ cypher=f"""
+ // Find principals with iam:PassRole permission
+ MATCH path_principal = (aws:AWSAccount {{id: $provider_uid}})--(principal:AWSPrincipal)--(passrole_policy:AWSPolicy)--(stmt_passrole:AWSPolicyStatement)
+ WHERE stmt_passrole.effect = 'Allow'
+ AND any(action IN stmt_passrole.action WHERE
+ toLower(action) = 'iam:passrole'
+ OR toLower(action) = 'iam:*'
+ OR action = '*'
+ )
+
+ // Find lambda:CreateFunction permission
+ MATCH (principal)--(create_policy:AWSPolicy)--(stmt_create:AWSPolicyStatement)
+ WHERE stmt_create.effect = 'Allow'
+ AND any(action IN stmt_create.action WHERE
+ toLower(action) = 'lambda:createfunction'
+ OR toLower(action) = 'lambda:*'
+ OR action = '*'
+ )
+
+ // Find lambda:AddPermission permission
+ MATCH (principal)--(perm_policy:AWSPolicy)--(stmt_perm:AWSPolicyStatement)
+ WHERE stmt_perm.effect = 'Allow'
+ AND any(action IN stmt_perm.action WHERE
+ toLower(action) = 'lambda:addpermission'
+ OR toLower(action) = 'lambda:*'
+ OR action = '*'
+ )
+
+ // Find roles that trust Lambda service (can be passed to Lambda)
+ MATCH path_target = (aws)--(target_role:AWSRole)-[:TRUSTS_AWS_PRINCIPAL]->(:AWSPrincipal {{arn: 'lambda.amazonaws.com'}})
+ WHERE any(resource IN stmt_passrole.resource WHERE
+ resource = '*'
+ OR target_role.arn CONTAINS resource
+ OR resource CONTAINS target_role.name
+ )
+
+ UNWIND nodes(path_principal) + nodes(path_target) as n
+ OPTIONAL MATCH (n)-[pfr]-(pf:{PROWLER_FINDING_LABEL} {{status: 'FAIL', provider_uid: $provider_uid}})
+
+ RETURN path_principal, path_target,
+ collect(DISTINCT pf) as dpf, collect(DISTINCT pfr) as dpfr
+ """,
+ parameters=[],
+)
+
+# SAGEMAKER-001
+AWS_SAGEMAKER_PRIVESC_PASSROLE_CREATE_NOTEBOOK = AttackPathsQueryDefinition(
+ id="aws-sagemaker-privesc-passrole-create-notebook",
+ name="SageMaker Notebook Creation with Privileged Role (SAGEMAKER-001)",
+ short_description="Create a SageMaker notebook instance with a privileged IAM role to execute arbitrary code with the role's permissions via the Jupyter environment.",
+ description="Detect principals who can create SageMaker notebook instances with privileged IAM roles. By passing a privileged role to a new notebook instance, the attacker gains shell access through the Jupyter environment and can execute arbitrary commands with the role's permissions.",
+ attribution=AttackPathsQueryAttribution(
+ text="pathfinding.cloud - SAGEMAKER-001 - iam:PassRole + sagemaker:CreateNotebookInstance",
+ link="https://pathfinding.cloud/paths/sagemaker-001",
+ ),
+ provider="aws",
+ cypher=f"""
+ // Find principals with iam:PassRole permission
+ MATCH path_principal = (aws:AWSAccount {{id: $provider_uid}})--(principal:AWSPrincipal)--(passrole_policy:AWSPolicy)--(stmt_passrole:AWSPolicyStatement)
+ WHERE stmt_passrole.effect = 'Allow'
+ AND any(action IN stmt_passrole.action WHERE
+ toLower(action) = 'iam:passrole'
+ OR toLower(action) = 'iam:*'
+ OR action = '*'
+ )
+
+ // Find sagemaker:CreateNotebookInstance permission
+ MATCH (principal)--(sm_policy:AWSPolicy)--(stmt_sm:AWSPolicyStatement)
+ WHERE stmt_sm.effect = 'Allow'
+ AND any(action IN stmt_sm.action WHERE
+ toLower(action) = 'sagemaker:createnotebookinstance'
+ OR toLower(action) = 'sagemaker:*'
+ OR action = '*'
+ )
+
+ // Find roles that trust SageMaker service (can be passed to SageMaker)
+ MATCH path_target = (aws)--(target_role:AWSRole)-[:TRUSTS_AWS_PRINCIPAL]->(:AWSPrincipal {{arn: 'sagemaker.amazonaws.com'}})
+ WHERE any(resource IN stmt_passrole.resource WHERE
+ resource = '*'
+ OR target_role.arn CONTAINS resource
+ OR resource CONTAINS target_role.name
+ )
+
+ UNWIND nodes(path_principal) + nodes(path_target) as n
+ OPTIONAL MATCH (n)-[pfr]-(pf:{PROWLER_FINDING_LABEL} {{status: 'FAIL', provider_uid: $provider_uid}})
+
+ RETURN path_principal, path_target,
+ collect(DISTINCT pf) as dpf, collect(DISTINCT pfr) as dpfr
+ """,
+ parameters=[],
+)
+
+# SAGEMAKER-002
+AWS_SAGEMAKER_PRIVESC_PASSROLE_CREATE_TRAINING_JOB = AttackPathsQueryDefinition(
+ id="aws-sagemaker-privesc-passrole-create-training-job",
+ name="SageMaker Training Job Creation with Privileged Role (SAGEMAKER-002)",
+ short_description="Create a SageMaker training job with a privileged IAM role to execute arbitrary container code with the role's permissions.",
+ description="Detect principals who can create SageMaker training jobs with privileged IAM roles. By passing a privileged role to a new training job with a malicious training script or container, the attacker executes code with elevated privileges and can exfiltrate credentials or modify AWS resources.",
+ attribution=AttackPathsQueryAttribution(
+ text="pathfinding.cloud - SAGEMAKER-002 - iam:PassRole + sagemaker:CreateTrainingJob",
+ link="https://pathfinding.cloud/paths/sagemaker-002",
+ ),
+ provider="aws",
+ cypher=f"""
+ // Find principals with iam:PassRole permission
+ MATCH path_principal = (aws:AWSAccount {{id: $provider_uid}})--(principal:AWSPrincipal)--(passrole_policy:AWSPolicy)--(stmt_passrole:AWSPolicyStatement)
+ WHERE stmt_passrole.effect = 'Allow'
+ AND any(action IN stmt_passrole.action WHERE
+ toLower(action) = 'iam:passrole'
+ OR toLower(action) = 'iam:*'
+ OR action = '*'
+ )
+
+ // Find sagemaker:CreateTrainingJob permission
+ MATCH (principal)--(sm_policy:AWSPolicy)--(stmt_sm:AWSPolicyStatement)
+ WHERE stmt_sm.effect = 'Allow'
+ AND any(action IN stmt_sm.action WHERE
+ toLower(action) = 'sagemaker:createtrainingjob'
+ OR toLower(action) = 'sagemaker:*'
+ OR action = '*'
+ )
+
+ // Find roles that trust SageMaker service (can be passed to SageMaker)
+ MATCH path_target = (aws)--(target_role:AWSRole)-[:TRUSTS_AWS_PRINCIPAL]->(:AWSPrincipal {{arn: 'sagemaker.amazonaws.com'}})
+ WHERE any(resource IN stmt_passrole.resource WHERE
+ resource = '*'
+ OR target_role.arn CONTAINS resource
+ OR resource CONTAINS target_role.name
+ )
+
+ UNWIND nodes(path_principal) + nodes(path_target) as n
+ OPTIONAL MATCH (n)-[pfr]-(pf:{PROWLER_FINDING_LABEL} {{status: 'FAIL', provider_uid: $provider_uid}})
+
+ RETURN path_principal, path_target,
+ collect(DISTINCT pf) as dpf, collect(DISTINCT pfr) as dpfr
+ """,
+ parameters=[],
+)
+
+# SAGEMAKER-003
+AWS_SAGEMAKER_PRIVESC_PASSROLE_CREATE_PROCESSING_JOB = AttackPathsQueryDefinition(
+ id="aws-sagemaker-privesc-passrole-create-processing-job",
+ name="SageMaker Processing Job Creation with Privileged Role (SAGEMAKER-003)",
+ short_description="Create a SageMaker processing job with a privileged IAM role to execute arbitrary container code with the role's permissions.",
+ description="Detect principals who can create SageMaker processing jobs with privileged IAM roles. By passing a privileged role to a new processing job with a malicious script or container, the attacker executes code with elevated privileges and can exfiltrate credentials or modify AWS resources.",
+ attribution=AttackPathsQueryAttribution(
+ text="pathfinding.cloud - SAGEMAKER-003 - iam:PassRole + sagemaker:CreateProcessingJob",
+ link="https://pathfinding.cloud/paths/sagemaker-003",
+ ),
+ provider="aws",
+ cypher=f"""
+ // Find principals with iam:PassRole permission
+ MATCH path_principal = (aws:AWSAccount {{id: $provider_uid}})--(principal:AWSPrincipal)--(passrole_policy:AWSPolicy)--(stmt_passrole:AWSPolicyStatement)
+ WHERE stmt_passrole.effect = 'Allow'
+ AND any(action IN stmt_passrole.action WHERE
+ toLower(action) = 'iam:passrole'
+ OR toLower(action) = 'iam:*'
+ OR action = '*'
+ )
+
+ // Find sagemaker:CreateProcessingJob permission
+ MATCH (principal)--(sm_policy:AWSPolicy)--(stmt_sm:AWSPolicyStatement)
+ WHERE stmt_sm.effect = 'Allow'
+ AND any(action IN stmt_sm.action WHERE
+ toLower(action) = 'sagemaker:createprocessingjob'
+ OR toLower(action) = 'sagemaker:*'
+ OR action = '*'
+ )
+
+ // Find roles that trust SageMaker service (can be passed to SageMaker)
+ MATCH path_target = (aws)--(target_role:AWSRole)-[:TRUSTS_AWS_PRINCIPAL]->(:AWSPrincipal {{arn: 'sagemaker.amazonaws.com'}})
+ WHERE any(resource IN stmt_passrole.resource WHERE
+ resource = '*'
+ OR target_role.arn CONTAINS resource
+ OR resource CONTAINS target_role.name
+ )
+
+ UNWIND nodes(path_principal) + nodes(path_target) as n
+ OPTIONAL MATCH (n)-[pfr]-(pf:{PROWLER_FINDING_LABEL} {{status: 'FAIL', provider_uid: $provider_uid}})
+
+ RETURN path_principal, path_target,
+ collect(DISTINCT pf) as dpf, collect(DISTINCT pfr) as dpfr
+ """,
+ parameters=[],
+)
+
+# SAGEMAKER-004
+AWS_SAGEMAKER_PRIVESC_PRESIGNED_NOTEBOOK_URL = AttackPathsQueryDefinition(
+ id="aws-sagemaker-privesc-presigned-notebook-url",
+ name="SageMaker Presigned Notebook URL for Privilege Escalation (SAGEMAKER-004)",
+ short_description="Generate a presigned URL to access an existing SageMaker notebook instance and execute code with its execution role's permissions.",
+ description="Detect principals who can generate presigned URLs to access existing SageMaker notebook instances. By accessing the Jupyter environment via a presigned URL, the attacker can execute arbitrary code with the permissions of the notebook's execution role without creating any new resources.",
+ attribution=AttackPathsQueryAttribution(
+ text="pathfinding.cloud - SAGEMAKER-004 - sagemaker:CreatePresignedNotebookInstanceUrl",
+ link="https://pathfinding.cloud/paths/sagemaker-004",
+ ),
+ provider="aws",
+ cypher=f"""
+ // Find principals with sagemaker:CreatePresignedNotebookInstanceUrl permission
+ MATCH path_principal = (aws:AWSAccount {{id: $provider_uid}})--(principal:AWSPrincipal)--(policy:AWSPolicy)--(stmt:AWSPolicyStatement)
+ WHERE stmt.effect = 'Allow'
+ AND any(action IN stmt.action WHERE
+ toLower(action) = 'sagemaker:createpresignednotebookinstanceurl'
+ OR toLower(action) = 'sagemaker:*'
+ OR action = '*'
+ )
+
+ // Find existing SageMaker notebook instances with execution roles
+ MATCH path_target = (aws)-[:RESOURCE]->(notebook:AWSSageMakerNotebookInstance)-[:HAS_EXECUTION_ROLE]->(target_role:AWSRole)
+ WHERE any(resource IN stmt.resource WHERE
+ resource = '*'
+ OR notebook.arn CONTAINS resource
+ OR resource CONTAINS notebook.notebook_instance_name
+ )
+
+ UNWIND nodes(path_principal) + nodes(path_target) as n
+ OPTIONAL MATCH (n)-[pfr]-(pf:{PROWLER_FINDING_LABEL} {{status: 'FAIL', provider_uid: $provider_uid}})
+
+ RETURN path_principal, path_target,
+ collect(DISTINCT pf) as dpf, collect(DISTINCT pfr) as dpfr
+ """,
+ parameters=[],
+)
+
+# SAGEMAKER-005
+AWS_SAGEMAKER_PRIVESC_LIFECYCLE_CONFIG_NOTEBOOK = AttackPathsQueryDefinition(
+ id="aws-sagemaker-privesc-lifecycle-config-notebook",
+ name="SageMaker Notebook Lifecycle Config Injection (SAGEMAKER-005)",
+ short_description="Inject a malicious lifecycle configuration into an existing SageMaker notebook to execute code with the notebook's execution role during startup.",
+ description="Detect principals who can inject malicious lifecycle configurations into existing SageMaker notebook instances. By stopping a notebook, attaching a malicious lifecycle config, and restarting it, the attacker executes arbitrary code with the notebook's execution role permissions during startup.",
+ attribution=AttackPathsQueryAttribution(
+ text="pathfinding.cloud - SAGEMAKER-005 - sagemaker:CreateNotebookInstanceLifecycleConfig + sagemaker:StopNotebookInstance + sagemaker:UpdateNotebookInstance + sagemaker:StartNotebookInstance",
+ link="https://pathfinding.cloud/paths/sagemaker-005",
+ ),
+ provider="aws",
+ cypher=f"""
+ // Find principals with sagemaker:CreateNotebookInstanceLifecycleConfig permission
+ MATCH path_principal = (aws:AWSAccount {{id: $provider_uid}})--(principal:AWSPrincipal)--(policy:AWSPolicy)--(stmt:AWSPolicyStatement)
+ WHERE stmt.effect = 'Allow'
+ AND any(action IN stmt.action WHERE
+ toLower(action) = 'sagemaker:createnotebookinstancelifecycleconfig'
+ OR toLower(action) = 'sagemaker:*'
+ OR action = '*'
+ )
+
+ // Find sagemaker:UpdateNotebookInstance permission
+ MATCH (principal)--(policy2:AWSPolicy)--(stmt2:AWSPolicyStatement)
+ WHERE stmt2.effect = 'Allow'
+ AND any(action IN stmt2.action WHERE
+ toLower(action) = 'sagemaker:updatenotebookinstance'
+ OR toLower(action) = 'sagemaker:*'
+ OR action = '*'
+ )
+
+ // Find sagemaker:StopNotebookInstance permission
+ MATCH (principal)--(policy3:AWSPolicy)--(stmt3:AWSPolicyStatement)
+ WHERE stmt3.effect = 'Allow'
+ AND any(action IN stmt3.action WHERE
+ toLower(action) = 'sagemaker:stopnotebookinstance'
+ OR toLower(action) = 'sagemaker:*'
+ OR action = '*'
+ )
+
+ // Find sagemaker:StartNotebookInstance permission
+ MATCH (principal)--(policy4:AWSPolicy)--(stmt4:AWSPolicyStatement)
+ WHERE stmt4.effect = 'Allow'
+ AND any(action IN stmt4.action WHERE
+ toLower(action) = 'sagemaker:startnotebookinstance'
+ OR toLower(action) = 'sagemaker:*'
+ OR action = '*'
+ )
+
+ // Find existing SageMaker notebook instances with execution roles
+ MATCH path_target = (aws)-[:RESOURCE]->(notebook:AWSSageMakerNotebookInstance)-[:HAS_EXECUTION_ROLE]->(target_role:AWSRole)
+ WHERE any(resource IN stmt2.resource WHERE
+ resource = '*'
+ OR notebook.arn CONTAINS resource
+ OR resource CONTAINS notebook.notebook_instance_name
+ )
+
+ UNWIND nodes(path_principal) + nodes(path_target) as n
+ OPTIONAL MATCH (n)-[pfr]-(pf:{PROWLER_FINDING_LABEL} {{status: 'FAIL', provider_uid: $provider_uid}})
+
+ RETURN path_principal, path_target,
+ collect(DISTINCT pf) as dpf, collect(DISTINCT pfr) as dpfr
+ """,
+ parameters=[],
+)
+
+# SSM-001
+AWS_SSM_PRIVESC_START_SESSION = AttackPathsQueryDefinition(
+ id="aws-ssm-privesc-start-session",
+ name="SSM Session Access for EC2 Role Credentials (SSM-001)",
+ short_description="Start an SSM session on an EC2 instance to access its attached role credentials through IMDS.",
+ description="Detect principals who can start SSM sessions on EC2 instances. This allows establishing a shell session on a running EC2 instance and retrieving the attached IAM role's temporary credentials from the Instance Metadata Service (IMDS), gaining that role's permissions.",
+ attribution=AttackPathsQueryAttribution(
+ text="pathfinding.cloud - SSM-001 - ssm:StartSession",
+ link="https://pathfinding.cloud/paths/ssm-001",
+ ),
+ provider="aws",
+ cypher=f"""
+ // Find principals with ssm:StartSession permission
+ MATCH path_principal = (aws:AWSAccount {{id: $provider_uid}})--(principal:AWSPrincipal)--(policy:AWSPolicy)--(stmt:AWSPolicyStatement)
+ WHERE stmt.effect = 'Allow'
+ AND any(action IN stmt.action WHERE
+ toLower(action) = 'ssm:startsession'
+ OR toLower(action) = 'ssm:*'
+ OR action = '*'
+ )
+
+ // Find EC2 instances with attached roles (targets for credential theft via IMDS)
+ MATCH path_target = (aws)--(ec2:EC2Instance)-[:STS_ASSUMEROLE_ALLOW]->(target_role:AWSRole)
+
+ UNWIND nodes(path_principal) + nodes(path_target) as n
+ OPTIONAL MATCH (n)-[pfr]-(pf:{PROWLER_FINDING_LABEL} {{status: 'FAIL', provider_uid: $provider_uid}})
+
+ RETURN path_principal, path_target,
+ collect(DISTINCT pf) as dpf, collect(DISTINCT pfr) as dpfr
+ """,
+ parameters=[],
+)
+
+# SSM-002
+AWS_SSM_PRIVESC_SEND_COMMAND = AttackPathsQueryDefinition(
+ id="aws-ssm-privesc-send-command",
+ name="SSM Send Command for EC2 Role Credentials (SSM-002)",
+ short_description="Execute commands on an EC2 instance via SSM Run Command to access its attached role credentials through IMDS.",
+ description="Detect principals who can send SSM commands to EC2 instances. This allows executing arbitrary commands on a running EC2 instance and retrieving the attached IAM role's temporary credentials from the Instance Metadata Service (IMDS), gaining that role's permissions.",
+ attribution=AttackPathsQueryAttribution(
+ text="pathfinding.cloud - SSM-002 - ssm:SendCommand",
+ link="https://pathfinding.cloud/paths/ssm-002",
+ ),
+ provider="aws",
+ cypher=f"""
+ // Find principals with ssm:SendCommand permission
+ MATCH path_principal = (aws:AWSAccount {{id: $provider_uid}})--(principal:AWSPrincipal)--(policy:AWSPolicy)--(stmt:AWSPolicyStatement)
+ WHERE stmt.effect = 'Allow'
+ AND any(action IN stmt.action WHERE
+ toLower(action) = 'ssm:sendcommand'
+ OR toLower(action) = 'ssm:*'
+ OR action = '*'
+ )
+
+ // Find EC2 instances with attached roles (targets for credential theft via IMDS)
+ MATCH path_target = (aws)--(ec2:EC2Instance)-[:STS_ASSUMEROLE_ALLOW]->(target_role:AWSRole)
+
+ UNWIND nodes(path_principal) + nodes(path_target) as n
+ OPTIONAL MATCH (n)-[pfr]-(pf:{PROWLER_FINDING_LABEL} {{status: 'FAIL', provider_uid: $provider_uid}})
+
+ RETURN path_principal, path_target,
+ collect(DISTINCT pf) as dpf, collect(DISTINCT pfr) as dpfr
+ """,
+ parameters=[],
+)
+
+# STS-001
+AWS_STS_PRIVESC_ASSUME_ROLE = AttackPathsQueryDefinition(
+ id="aws-sts-privesc-assume-role",
+ name="Role Assumption for Privilege Escalation (STS-001)",
+ short_description="Assume IAM roles with elevated permissions by exploiting bidirectional trust between the starting principal and the target role.",
+ description="Detect principals who can assume other IAM roles via sts:AssumeRole. When a principal has sts:AssumeRole permission and the target role's trust policy allows the principal to assume it (bidirectional trust), the attacker gains all permissions of the target role. This enables privilege escalation when the target role has higher privileges than the starting principal.",
+ attribution=AttackPathsQueryAttribution(
+ text="pathfinding.cloud - STS-001 - sts:AssumeRole",
+ link="https://pathfinding.cloud/paths/sts-001",
+ ),
+ provider="aws",
+ cypher=f"""
+ // Find principals with sts:AssumeRole permission
+ MATCH path_principal = (aws:AWSAccount {{id: $provider_uid}})--(principal:AWSPrincipal)--(policy:AWSPolicy)--(stmt:AWSPolicyStatement)
+ WHERE stmt.effect = 'Allow'
+ AND any(action IN stmt.action WHERE
toLower(action) = 'sts:assumerole'
OR toLower(action) = 'sts:*'
OR action = '*'
)
- // Find target roles that the principal can both modify AND assume
- MATCH path_target = (aws)--(target_role:AWSRole)
- WHERE target_role.arn CONTAINS $provider_uid
- // Can attach policy to this role
- AND any(resource IN stmt_attach.resource WHERE
- resource = '*'
- OR target_role.arn CONTAINS resource
- OR resource CONTAINS target_role.name
- )
- // Can assume this role
- AND any(resource IN stmt_assume.resource WHERE
- resource = '*'
- OR target_role.arn CONTAINS resource
- OR resource CONTAINS target_role.name
- )
-
- // Deduplicate before creating virtual relationships
- WITH DISTINCT admin_outcome, aws, principal, target_role
-
- // Create virtual relationships showing the attack path
- CALL apoc.create.vRelationship(principal, 'CAN_MODIFY', {{
- via: 'iam:AttachRolePolicy'
- }}, target_role)
- YIELD rel AS modify_rel
-
- CALL apoc.create.vRelationship(target_role, 'LEADS_TO', {{
- technique: 'iam:AttachRolePolicy + sts:AssumeRole',
- via: 'sts:AssumeRole',
- reference: 'https://pathfinding.cloud/paths/iam-014'
- }}, admin_outcome)
- YIELD rel AS escalation_rel
-
- // Re-match paths for visualization
- MATCH path_principal = (aws)--(principal)
- MATCH path_target = (aws)--(target_role)
+ // Find target roles the principal can assume (bidirectional trust via Cartography)
+ MATCH path_target = (aws)--(target_role:AWSRole)<-[:STS_ASSUMEROLE_ALLOW]-(principal)
+ WHERE any(resource IN stmt.resource WHERE
+ resource = '*'
+ OR target_role.arn CONTAINS resource
+ OR resource CONTAINS target_role.name
+ )
UNWIND nodes(path_principal) + nodes(path_target) as n
- OPTIONAL MATCH (n)-[pfr]-(pf:{PROWLER_FINDING_LABEL})
- WHERE pf.status = 'FAIL'
+ OPTIONAL MATCH (n)-[pfr]-(pf:{PROWLER_FINDING_LABEL} {{status: 'FAIL', provider_uid: $provider_uid}})
RETURN path_principal, path_target,
- admin_outcome, modify_rel, escalation_rel,
- collect(DISTINCT pf) as dpf, collect(DISTINCT pfr) as dpfr
+ collect(DISTINCT pf) as dpf, collect(DISTINCT pfr) as dpfr
""",
parameters=[],
)
-# TODO: Add ProwlerFinding nodes
-AWS_BEDROCK_PRIVESC_PASSROLE_CODE_INTERPRETER = AttackPathsQueryDefinition(
- id="aws-bedrock-privesc-passrole-code-interpreter",
- name="Privilege Escalation: Bedrock Code Interpreter with PassRole",
- description="Detect principals that can escalate privileges by passing a role to a Bedrock AgentCore Code Interpreter. The attacker creates a code interpreter with an arbitrary role, then invokes it to execute code with those credentials.",
- provider="aws",
- cypher="""
- CALL apoc.create.vNode(['PrivilegeEscalation'], {
- id: 'effective-administrator-bedrock',
- check_title: 'Privilege Escalation',
- name: 'Effective Administrator (Bedrock)',
- status: 'FAIL',
- severity: 'critical'
- })
- YIELD node AS escalation_outcome
-
- WITH escalation_outcome
-
- // Find principals in the account
- MATCH path_principal = (aws:AWSAccount {id: $provider_uid})--(principal:AWSPrincipal)
-
- // Principal can assume roles (up to 2 hops)
- OPTIONAL MATCH path_assume = (principal)-[:STS_ASSUMEROLE_ALLOW*0..2]->(acting_as:AWSRole)
- WITH escalation_outcome, aws, principal, path_principal, path_assume,
- CASE WHEN path_assume IS NULL THEN principal ELSE acting_as END AS effective_principal
-
- // Find iam:PassRole permission
- MATCH path_passrole = (effective_principal)--(passrole_policy:AWSPolicy)--(passrole_stmt:AWSPolicyStatement)
- WHERE passrole_stmt.effect = 'Allow'
- AND any(action IN passrole_stmt.action WHERE toLower(action) = 'iam:passrole' OR action = '*')
-
- // Find Bedrock AgentCore permissions
- MATCH (effective_principal)--(bedrock_policy:AWSPolicy)--(bedrock_stmt:AWSPolicyStatement)
- WHERE bedrock_stmt.effect = 'Allow'
- AND (
- any(action IN bedrock_stmt.action WHERE toLower(action) = 'bedrock-agentcore:createcodeinterpreter' OR action = '*' OR toLower(action) = 'bedrock-agentcore:*')
- )
- AND (
- any(action IN bedrock_stmt.action WHERE toLower(action) = 'bedrock-agentcore:startsession' OR action = '*' OR toLower(action) = 'bedrock-agentcore:*')
- )
- AND (
- any(action IN bedrock_stmt.action WHERE toLower(action) = 'bedrock-agentcore:invoke' OR action = '*' OR toLower(action) = 'bedrock-agentcore:*')
- )
-
- // Find target roles with elevated permissions that could be passed
- MATCH (aws)--(target_role:AWSRole)--(target_policy:AWSPolicy)--(target_stmt:AWSPolicyStatement)
- WHERE target_stmt.effect = 'Allow'
- AND (
- any(action IN target_stmt.action WHERE action = '*')
- OR any(action IN target_stmt.action WHERE toLower(action) = 'iam:*')
- )
-
- // Deduplicate per (principal, target_role) pair
- WITH DISTINCT escalation_outcome, aws, principal, target_role
-
- // Group by principal, collect target_roles
- WITH escalation_outcome, aws, principal,
- collect(DISTINCT target_role) AS target_roles,
- count(DISTINCT target_role) AS target_count
-
- // Create single virtual Bedrock node per principal
- CALL apoc.create.vNode(['BedrockCodeInterpreter'], {
- name: 'New Code Interpreter',
- description: toString(target_count) + ' admin role(s) can be passed',
- id: principal.arn,
- target_role_count: target_count
- })
- YIELD node AS bedrock_agent
-
- // Connect from principal (not effective_principal) to keep graph connected
- CALL apoc.create.vRelationship(principal, 'CREATES_INTERPRETER', {
- permissions: ['iam:PassRole', 'bedrock-agentcore:CreateCodeInterpreter', 'bedrock-agentcore:StartSession', 'bedrock-agentcore:Invoke'],
- technique: 'new-passrole'
- }, bedrock_agent)
- YIELD rel AS create_rel
-
- // UNWIND target_roles to show which roles can be passed
- UNWIND target_roles AS target_role
-
- CALL apoc.create.vRelationship(bedrock_agent, 'PASSES_ROLE', {}, target_role)
- YIELD rel AS pass_rel
-
- CALL apoc.create.vRelationship(target_role, 'GRANTS_ACCESS', {
- reference: 'https://pathfinding.cloud/paths/bedrock-001'
- }, escalation_outcome)
- YIELD rel AS grants_rel
-
- // Re-match path for visualization
- MATCH path_principal = (aws)--(principal)
-
- RETURN path_principal,
- bedrock_agent, target_role, escalation_outcome, create_rel, pass_rel, grants_rel, target_count
- """,
- parameters=[],
-)
-
-
# AWS Queries List
# ----------------
@@ -688,8 +3390,70 @@ AWS_QUERIES: list[AttackPathsQueryDefinition] = [
AWS_CLASSIC_ELB_INTERNET_EXPOSED,
AWS_ELBV2_INTERNET_EXPOSED,
AWS_PUBLIC_IP_RESOURCE_LOOKUP,
- AWS_IAM_PRIVESC_PASSROLE_EC2,
- AWS_GLUE_PRIVESC_PASSROLE_DEV_ENDPOINT,
- AWS_IAM_PRIVESC_ATTACH_ROLE_POLICY_ASSUME_ROLE,
+ AWS_APPRUNNER_PRIVESC_PASSROLE_CREATE_SERVICE,
+ AWS_APPRUNNER_PRIVESC_UPDATE_SERVICE,
AWS_BEDROCK_PRIVESC_PASSROLE_CODE_INTERPRETER,
+ AWS_BEDROCK_PRIVESC_INVOKE_CODE_INTERPRETER,
+ AWS_CLOUDFORMATION_PRIVESC_PASSROLE_CREATE_STACK,
+ AWS_CLOUDFORMATION_PRIVESC_UPDATE_STACK,
+ AWS_CLOUDFORMATION_PRIVESC_PASSROLE_CREATE_STACKSET,
+ AWS_CLOUDFORMATION_PRIVESC_PASSROLE_UPDATE_STACKSET,
+ AWS_CLOUDFORMATION_PRIVESC_CHANGESET,
+ AWS_CODEBUILD_PRIVESC_PASSROLE_CREATE_PROJECT,
+ AWS_CODEBUILD_PRIVESC_START_BUILD,
+ AWS_CODEBUILD_PRIVESC_START_BUILD_BATCH,
+ AWS_CODEBUILD_PRIVESC_PASSROLE_CREATE_PROJECT_BATCH,
+ AWS_DATAPIPELINE_PRIVESC_PASSROLE_CREATE_PIPELINE,
+ AWS_EC2_PRIVESC_PASSROLE_IAM,
+ AWS_EC2_PRIVESC_MODIFY_INSTANCE_ATTRIBUTE,
+ AWS_EC2_PRIVESC_PASSROLE_SPOT_INSTANCES,
+ AWS_EC2_PRIVESC_LAUNCH_TEMPLATE,
+ AWS_EC2INSTANCECONNECT_PRIVESC_SEND_SSH_PUBLIC_KEY,
+ AWS_ECS_PRIVESC_PASSROLE_CREATE_SERVICE,
+ AWS_ECS_PRIVESC_PASSROLE_RUN_TASK,
+ AWS_ECS_PRIVESC_PASSROLE_CREATE_SERVICE_EXISTING_CLUSTER,
+ AWS_ECS_PRIVESC_PASSROLE_RUN_TASK_EXISTING_CLUSTER,
+ AWS_ECS_PRIVESC_PASSROLE_START_TASK_EXISTING_CLUSTER,
+ AWS_ECS_PRIVESC_EXECUTE_COMMAND,
+ AWS_GLUE_PRIVESC_PASSROLE_DEV_ENDPOINT,
+ AWS_GLUE_PRIVESC_UPDATE_DEV_ENDPOINT,
+ AWS_GLUE_PRIVESC_PASSROLE_CREATE_JOB,
+ AWS_GLUE_PRIVESC_PASSROLE_CREATE_JOB_TRIGGER,
+ AWS_GLUE_PRIVESC_PASSROLE_UPDATE_JOB,
+ AWS_GLUE_PRIVESC_PASSROLE_UPDATE_JOB_TRIGGER,
+ AWS_IAM_PRIVESC_CREATE_POLICY_VERSION,
+ AWS_IAM_PRIVESC_CREATE_ACCESS_KEY,
+ AWS_IAM_PRIVESC_DELETE_CREATE_ACCESS_KEY,
+ AWS_IAM_PRIVESC_CREATE_LOGIN_PROFILE,
+ AWS_IAM_PRIVESC_PUT_ROLE_POLICY,
+ AWS_IAM_PRIVESC_UPDATE_LOGIN_PROFILE,
+ AWS_IAM_PRIVESC_PUT_USER_POLICY,
+ AWS_IAM_PRIVESC_ATTACH_USER_POLICY,
+ AWS_IAM_PRIVESC_ATTACH_ROLE_POLICY,
+ AWS_IAM_PRIVESC_ATTACH_GROUP_POLICY,
+ AWS_IAM_PRIVESC_PUT_GROUP_POLICY,
+ AWS_IAM_PRIVESC_UPDATE_ASSUME_ROLE_POLICY,
+ AWS_IAM_PRIVESC_ADD_USER_TO_GROUP,
+ AWS_IAM_PRIVESC_ATTACH_ROLE_POLICY_ASSUME_ROLE,
+ AWS_IAM_PRIVESC_ATTACH_USER_POLICY_CREATE_ACCESS_KEY,
+ AWS_IAM_PRIVESC_CREATE_POLICY_VERSION_ASSUME_ROLE,
+ AWS_IAM_PRIVESC_PUT_ROLE_POLICY_ASSUME_ROLE,
+ AWS_IAM_PRIVESC_PUT_USER_POLICY_CREATE_ACCESS_KEY,
+ AWS_IAM_PRIVESC_ATTACH_ROLE_POLICY_UPDATE_ASSUME_ROLE,
+ AWS_IAM_PRIVESC_CREATE_POLICY_VERSION_UPDATE_ASSUME_ROLE,
+ AWS_IAM_PRIVESC_PUT_ROLE_POLICY_UPDATE_ASSUME_ROLE,
+ AWS_LAMBDA_PRIVESC_PASSROLE_CREATE_FUNCTION,
+ AWS_LAMBDA_PRIVESC_PASSROLE_CREATE_FUNCTION_EVENT_SOURCE,
+ AWS_LAMBDA_PRIVESC_UPDATE_FUNCTION_CODE,
+ AWS_LAMBDA_PRIVESC_UPDATE_FUNCTION_CODE_INVOKE,
+ AWS_LAMBDA_PRIVESC_UPDATE_FUNCTION_CODE_ADD_PERMISSION,
+ AWS_LAMBDA_PRIVESC_PASSROLE_CREATE_FUNCTION_ADD_PERMISSION,
+ AWS_SAGEMAKER_PRIVESC_PASSROLE_CREATE_NOTEBOOK,
+ AWS_SAGEMAKER_PRIVESC_PASSROLE_CREATE_TRAINING_JOB,
+ AWS_SAGEMAKER_PRIVESC_PASSROLE_CREATE_PROCESSING_JOB,
+ AWS_SAGEMAKER_PRIVESC_PRESIGNED_NOTEBOOK_URL,
+ AWS_SAGEMAKER_PRIVESC_LIFECYCLE_CONFIG_NOTEBOOK,
+ AWS_SSM_PRIVESC_START_SESSION,
+ AWS_SSM_PRIVESC_SEND_COMMAND,
+ AWS_STS_PRIVESC_ASSUME_ROLE,
]
diff --git a/api/src/backend/api/attack_paths/queries/types.py b/api/src/backend/api/attack_paths/queries/types.py
index d798dbbcdb..3a70805cd7 100644
--- a/api/src/backend/api/attack_paths/queries/types.py
+++ b/api/src/backend/api/attack_paths/queries/types.py
@@ -1,6 +1,14 @@
from dataclasses import dataclass, field
+@dataclass
+class AttackPathsQueryAttribution:
+ """Source attribution for an Attack Path query."""
+
+ text: str
+ link: str
+
+
@dataclass
class AttackPathsQueryParameterDefinition:
"""
@@ -23,7 +31,9 @@ class AttackPathsQueryDefinition:
id: str
name: str
+ short_description: str
description: str
provider: str
cypher: str
+ attribution: AttackPathsQueryAttribution | None = None
parameters: list[AttackPathsQueryParameterDefinition] = field(default_factory=list)
diff --git a/api/src/backend/api/attack_paths/views_helpers.py b/api/src/backend/api/attack_paths/views_helpers.py
index cb14c7f44b..b3e860a4b8 100644
--- a/api/src/backend/api/attack_paths/views_helpers.py
+++ b/api/src/backend/api/attack_paths/views_helpers.py
@@ -5,7 +5,6 @@ from typing import Any, Iterable
from rest_framework.exceptions import APIException, ValidationError
from api.attack_paths import database as graph_database, AttackPathsQueryDefinition
-from api.models import AttackPathsScan
from config.custom_logging import BackendLogger
from tasks.jobs.attack_paths.config import INTERNAL_LABELS
@@ -80,12 +79,12 @@ def prepare_query_parameters(
def execute_attack_paths_query(
- attack_paths_scan: AttackPathsScan,
+ database_name: str,
definition: AttackPathsQueryDefinition,
parameters: dict[str, Any],
) -> dict[str, Any]:
try:
- with graph_database.get_session(attack_paths_scan.graph_database) as session:
+ with graph_database.get_session(database_name) as session:
result = session.run(definition.cypher, parameters)
return _serialize_graph(result.graph())
diff --git a/api/src/backend/api/fixtures/dev/8_dev_attack_paths_scans.json b/api/src/backend/api/fixtures/dev/8_dev_attack_paths_scans.json
index fdf310458a..4f0c6e94ed 100644
--- a/api/src/backend/api/fixtures/dev/8_dev_attack_paths_scans.json
+++ b/api/src/backend/api/fixtures/dev/8_dev_attack_paths_scans.json
@@ -7,10 +7,9 @@
"provider": "b85601a8-4b45-4194-8135-03fb980ef428",
"scan": "01920573-aa9c-73c9-bcda-f2e35c9b19d2",
"state": "completed",
+ "graph_data_ready": true,
"progress": 100,
"update_tag": 1693586667,
- "graph_database": "db-a7f0f6de-6f8e-4b3a-8cbe-3f6dd9012345",
- "is_graph_database_deleted": false,
"task": null,
"inserted_at": "2024-09-01T17:24:37Z",
"updated_at": "2024-09-01T17:44:37Z",
@@ -30,8 +29,6 @@
"state": "executing",
"progress": 48,
"update_tag": 1697625000,
- "graph_database": "db-4a2fb2af-8a60-4d7d-9cae-4ca65e098765",
- "is_graph_database_deleted": false,
"task": null,
"inserted_at": "2024-10-18T10:55:57Z",
"updated_at": "2024-10-18T10:56:15Z",
diff --git a/api/src/backend/api/migrations/0076_openstack_provider.py b/api/src/backend/api/migrations/0076_openstack_provider.py
new file mode 100644
index 0000000000..9cc80707ea
--- /dev/null
+++ b/api/src/backend/api/migrations/0076_openstack_provider.py
@@ -0,0 +1,39 @@
+# Generated by Django migration for OpenStack provider support
+
+from django.db import migrations
+
+import api.db_utils
+
+
+class Migration(migrations.Migration):
+ dependencies = [
+ ("api", "0075_cloudflare_provider"),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name="provider",
+ name="provider",
+ field=api.db_utils.ProviderEnumField(
+ choices=[
+ ("aws", "AWS"),
+ ("azure", "Azure"),
+ ("gcp", "GCP"),
+ ("kubernetes", "Kubernetes"),
+ ("m365", "M365"),
+ ("github", "GitHub"),
+ ("mongodbatlas", "MongoDB Atlas"),
+ ("iac", "IaC"),
+ ("oraclecloud", "Oracle Cloud Infrastructure"),
+ ("alibabacloud", "Alibaba Cloud"),
+ ("cloudflare", "Cloudflare"),
+ ("openstack", "OpenStack"),
+ ],
+ default="aws",
+ ),
+ ),
+ migrations.RunSQL(
+ "ALTER TYPE provider ADD VALUE IF NOT EXISTS 'openstack';",
+ reverse_sql=migrations.RunSQL.noop,
+ ),
+ ]
diff --git a/api/src/backend/api/migrations/0077_remove_attackpathsscan_graph_database_indexes.py b/api/src/backend/api/migrations/0077_remove_attackpathsscan_graph_database_indexes.py
new file mode 100644
index 0000000000..0498b66e92
--- /dev/null
+++ b/api/src/backend/api/migrations/0077_remove_attackpathsscan_graph_database_indexes.py
@@ -0,0 +1,23 @@
+# Generated by Django 5.1.15 on 2026-02-16 09:24
+
+from django.contrib.postgres.operations import RemoveIndexConcurrently
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+ atomic = False
+
+ dependencies = [
+ ("api", "0076_openstack_provider"),
+ ]
+
+ operations = [
+ RemoveIndexConcurrently(
+ model_name="attackpathsscan",
+ name="aps_active_graph_idx",
+ ),
+ RemoveIndexConcurrently(
+ model_name="attackpathsscan",
+ name="aps_completed_graph_idx",
+ ),
+ ]
diff --git a/api/src/backend/api/migrations/0078_remove_attackpathsscan_graph_database_fields.py b/api/src/backend/api/migrations/0078_remove_attackpathsscan_graph_database_fields.py
new file mode 100644
index 0000000000..89c9558817
--- /dev/null
+++ b/api/src/backend/api/migrations/0078_remove_attackpathsscan_graph_database_fields.py
@@ -0,0 +1,20 @@
+# Generated by Django 5.1.15 on 2026-02-16 09:24
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+ dependencies = [
+ ("api", "0077_remove_attackpathsscan_graph_database_indexes"),
+ ]
+
+ operations = [
+ migrations.RemoveField(
+ model_name="attackpathsscan",
+ name="graph_database",
+ ),
+ migrations.RemoveField(
+ model_name="attackpathsscan",
+ name="is_graph_database_deleted",
+ ),
+ ]
diff --git a/api/src/backend/api/migrations/0079_attackpathsscan_graph_data_ready.py b/api/src/backend/api/migrations/0079_attackpathsscan_graph_data_ready.py
new file mode 100644
index 0000000000..1c9429c046
--- /dev/null
+++ b/api/src/backend/api/migrations/0079_attackpathsscan_graph_data_ready.py
@@ -0,0 +1,17 @@
+# Generated by Django 5.1.15 on 2026-02-16 13:55
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+ dependencies = [
+ ("api", "0078_remove_attackpathsscan_graph_database_fields"),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name="attackpathsscan",
+ name="graph_data_ready",
+ field=models.BooleanField(default=False),
+ ),
+ ]
diff --git a/api/src/backend/api/migrations/0080_backfill_attack_paths_graph_data_ready.py b/api/src/backend/api/migrations/0080_backfill_attack_paths_graph_data_ready.py
new file mode 100644
index 0000000000..f780059bd2
--- /dev/null
+++ b/api/src/backend/api/migrations/0080_backfill_attack_paths_graph_data_ready.py
@@ -0,0 +1,26 @@
+# Separate from 0079 because psqlextra's schema editor runs AddField DDL and DML
+# on different database connections, causing a deadlock when combined with RunPython
+# in the same migration.
+
+from django.db import migrations
+
+from api.db_router import MainRouter
+
+
+def backfill_graph_data_ready(apps, schema_editor):
+ """Set graph_data_ready=True for all completed AttackPathsScan rows."""
+ AttackPathsScan = apps.get_model("api", "AttackPathsScan")
+ AttackPathsScan.objects.using(MainRouter.admin_db).filter(
+ state="completed",
+ graph_data_ready=False,
+ ).update(graph_data_ready=True)
+
+
+class Migration(migrations.Migration):
+ dependencies = [
+ ("api", "0079_attackpathsscan_graph_data_ready"),
+ ]
+
+ operations = [
+ migrations.RunPython(backfill_graph_data_ready, migrations.RunPython.noop),
+ ]
diff --git a/api/src/backend/api/models.py b/api/src/backend/api/models.py
index 4bda51761c..5597963216 100644
--- a/api/src/backend/api/models.py
+++ b/api/src/backend/api/models.py
@@ -288,6 +288,7 @@ class Provider(RowLevelSecurityProtectedModel):
ORACLECLOUD = "oraclecloud", _("Oracle Cloud Infrastructure")
ALIBABACLOUD = "alibabacloud", _("Alibaba Cloud")
CLOUDFLARE = "cloudflare", _("Cloudflare")
+ OPENSTACK = "openstack", _("OpenStack")
@staticmethod
def validate_aws_uid(value):
@@ -326,10 +327,13 @@ class Provider(RowLevelSecurityProtectedModel):
@staticmethod
def validate_gcp_uid(value):
- if not re.match(r"^[a-z][a-z0-9-]{5,29}$", value):
+ # Standard format: 6-30 chars, starts with letter, lowercase + digits + hyphens
+ # Legacy App Engine format: domain.com:project-id
+ if not re.match(r"^([a-z][a-z0-9.-]*:)?[a-z][a-z0-9-]{5,29}$", value):
raise ModelValidationError(
- detail="GCP provider ID must be 6 to 30 characters, start with a letter, and contain only lowercase "
- "letters, numbers, and hyphens.",
+ detail="GCP provider ID must be a valid project ID: 6 to 30 characters, start with a letter, "
+ "and contain only lowercase letters, numbers, and hyphens. "
+ "Legacy App Engine project IDs with a domain prefix (e.g., example.com:my-project) are also accepted.",
code="gcp-uid",
pointer="/data/attributes/uid",
)
@@ -410,6 +414,15 @@ class Provider(RowLevelSecurityProtectedModel):
pointer="/data/attributes/uid",
)
+ @staticmethod
+ def validate_openstack_uid(value):
+ if not re.match(r"^[a-zA-Z0-9][a-zA-Z0-9._-]{0,254}$", value):
+ raise ModelValidationError(
+ detail="OpenStack provider ID must be a valid project ID (UUID or project name).",
+ code="openstack-uid",
+ pointer="/data/attributes/uid",
+ )
+
id = models.UUIDField(primary_key=True, default=uuid4, editable=False)
inserted_at = models.DateTimeField(auto_now_add=True, editable=False)
updated_at = models.DateTimeField(auto_now=True, editable=False)
@@ -645,6 +658,7 @@ class AttackPathsScan(RowLevelSecurityProtectedModel):
state = StateEnumField(choices=StateChoices.choices, default=StateChoices.AVAILABLE)
progress = models.IntegerField(default=0)
+ graph_data_ready = models.BooleanField(default=False)
# Timing
started_at = models.DateTimeField(null=True, blank=True)
@@ -681,8 +695,6 @@ class AttackPathsScan(RowLevelSecurityProtectedModel):
update_tag = models.BigIntegerField(
null=True, blank=True, help_text="Cartography update tag (epoch)"
)
- graph_database = models.CharField(max_length=63, null=True, blank=True)
- is_graph_database_deleted = models.BooleanField(default=False)
ingestion_exceptions = models.JSONField(default=dict, null=True, blank=True)
class Meta(RowLevelSecurityProtectedModel.Meta):
@@ -709,21 +721,6 @@ class AttackPathsScan(RowLevelSecurityProtectedModel):
fields=["tenant_id", "scan_id"],
name="aps_scan_lookup_idx",
),
- models.Index(
- fields=["tenant_id", "provider_id"],
- name="aps_active_graph_idx",
- include=["graph_database", "id"],
- condition=Q(is_graph_database_deleted=False),
- ),
- models.Index(
- fields=["tenant_id", "provider_id", "-completed_at"],
- name="aps_completed_graph_idx",
- include=["graph_database", "id"],
- condition=Q(
- state=StateChoices.COMPLETED,
- is_graph_database_deleted=False,
- ),
- ),
]
class JSONAPIMeta:
diff --git a/api/src/backend/api/specs/v1.yaml b/api/src/backend/api/specs/v1.yaml
index 432528c562..0a2b4327ca 100644
--- a/api/src/backend/api/specs/v1.yaml
+++ b/api/src/backend/api/specs/v1.yaml
@@ -296,6 +296,7 @@ paths:
enum:
- state
- progress
+ - graph_data_ready
- provider
- provider_alias
- provider_type
@@ -355,7 +356,7 @@ paths:
name: filter[provider_type]
schema:
type: string
- x-spec-enum-id: 2d8d323e9cc0044b
+ x-spec-enum-id: 4b8815b179aa7216
enum:
- alibabacloud
- aws
@@ -367,6 +368,7 @@ paths:
- kubernetes
- m365
- mongodbatlas
+ - openstack
- oraclecloud
description: |-
* `aws` - AWS
@@ -380,13 +382,14 @@ paths:
* `oraclecloud` - Oracle Cloud Infrastructure
* `alibabacloud` - Alibaba Cloud
* `cloudflare` - Cloudflare
+ * `openstack` - OpenStack
- in: query
name: filter[provider_type__in]
schema:
type: array
items:
type: string
- x-spec-enum-id: 2d8d323e9cc0044b
+ x-spec-enum-id: 4b8815b179aa7216
enum:
- alibabacloud
- aws
@@ -398,6 +401,7 @@ paths:
- kubernetes
- m365
- mongodbatlas
+ - openstack
- oraclecloud
description: |-
Multiple values may be separated by commas.
@@ -413,6 +417,7 @@ paths:
* `oraclecloud` - Oracle Cloud Infrastructure
* `alibabacloud` - Alibaba Cloud
* `cloudflare` - Cloudflare
+ * `openstack` - OpenStack
explode: false
style: form
- in: query
@@ -567,6 +572,7 @@ paths:
enum:
- state
- progress
+ - graph_data_ready
- provider
- provider_alias
- provider_type
@@ -616,7 +622,7 @@ paths:
operationId: attack_paths_scans_queries_retrieve
description: Retrieve the catalog of Attack Paths queries available for this
Attack Paths scan.
- summary: List attack paths queries
+ summary: List Attack Paths queries
parameters:
- in: query
name: fields[attack-paths-scans]
@@ -627,6 +633,7 @@ paths:
enum:
- state
- progress
+ - graph_data_ready
- provider
- provider_alias
- provider_type
@@ -714,7 +721,7 @@ paths:
description: Bad request (e.g., Unknown Attack Paths query for the selected
provider)
'404':
- description: No attack paths found for the given query and parameters
+ description: No Attack Paths found for the given query and parameters
'500':
description: Attack Paths query execution failed due to a database error
/api/v1/compliance-overviews:
@@ -1336,7 +1343,7 @@ paths:
name: filter[provider_type]
schema:
type: string
- x-spec-enum-id: 2d8d323e9cc0044b
+ x-spec-enum-id: 4b8815b179aa7216
enum:
- alibabacloud
- aws
@@ -1348,6 +1355,7 @@ paths:
- kubernetes
- m365
- mongodbatlas
+ - openstack
- oraclecloud
description: |-
* `aws` - AWS
@@ -1361,13 +1369,14 @@ paths:
* `oraclecloud` - Oracle Cloud Infrastructure
* `alibabacloud` - Alibaba Cloud
* `cloudflare` - Cloudflare
+ * `openstack` - OpenStack
- in: query
name: filter[provider_type__in]
schema:
type: array
items:
type: string
- x-spec-enum-id: 2d8d323e9cc0044b
+ x-spec-enum-id: 4b8815b179aa7216
enum:
- alibabacloud
- aws
@@ -1379,6 +1388,7 @@ paths:
- kubernetes
- m365
- mongodbatlas
+ - openstack
- oraclecloud
description: |-
Multiple values may be separated by commas.
@@ -1394,6 +1404,7 @@ paths:
* `oraclecloud` - Oracle Cloud Infrastructure
* `alibabacloud` - Alibaba Cloud
* `cloudflare` - Cloudflare
+ * `openstack` - OpenStack
explode: false
style: form
- in: query
@@ -1926,7 +1937,7 @@ paths:
name: filter[provider_type]
schema:
type: string
- x-spec-enum-id: 2d8d323e9cc0044b
+ x-spec-enum-id: 4b8815b179aa7216
enum:
- alibabacloud
- aws
@@ -1938,6 +1949,7 @@ paths:
- kubernetes
- m365
- mongodbatlas
+ - openstack
- oraclecloud
description: |-
* `aws` - AWS
@@ -1951,13 +1963,14 @@ paths:
* `oraclecloud` - Oracle Cloud Infrastructure
* `alibabacloud` - Alibaba Cloud
* `cloudflare` - Cloudflare
+ * `openstack` - OpenStack
- in: query
name: filter[provider_type__in]
schema:
type: array
items:
type: string
- x-spec-enum-id: 2d8d323e9cc0044b
+ x-spec-enum-id: 4b8815b179aa7216
enum:
- alibabacloud
- aws
@@ -1969,6 +1982,7 @@ paths:
- kubernetes
- m365
- mongodbatlas
+ - openstack
- oraclecloud
description: |-
Multiple values may be separated by commas.
@@ -1984,6 +1998,7 @@ paths:
* `oraclecloud` - Oracle Cloud Infrastructure
* `alibabacloud` - Alibaba Cloud
* `cloudflare` - Cloudflare
+ * `openstack` - OpenStack
explode: false
style: form
- in: query
@@ -2424,7 +2439,7 @@ paths:
name: filter[provider_type]
schema:
type: string
- x-spec-enum-id: 2d8d323e9cc0044b
+ x-spec-enum-id: 4b8815b179aa7216
enum:
- alibabacloud
- aws
@@ -2436,6 +2451,7 @@ paths:
- kubernetes
- m365
- mongodbatlas
+ - openstack
- oraclecloud
description: |-
* `aws` - AWS
@@ -2449,13 +2465,14 @@ paths:
* `oraclecloud` - Oracle Cloud Infrastructure
* `alibabacloud` - Alibaba Cloud
* `cloudflare` - Cloudflare
+ * `openstack` - OpenStack
- in: query
name: filter[provider_type__in]
schema:
type: array
items:
type: string
- x-spec-enum-id: 2d8d323e9cc0044b
+ x-spec-enum-id: 4b8815b179aa7216
enum:
- alibabacloud
- aws
@@ -2467,6 +2484,7 @@ paths:
- kubernetes
- m365
- mongodbatlas
+ - openstack
- oraclecloud
description: |-
Multiple values may be separated by commas.
@@ -2482,6 +2500,7 @@ paths:
* `oraclecloud` - Oracle Cloud Infrastructure
* `alibabacloud` - Alibaba Cloud
* `cloudflare` - Cloudflare
+ * `openstack` - OpenStack
explode: false
style: form
- in: query
@@ -2920,7 +2939,7 @@ paths:
name: filter[provider_type]
schema:
type: string
- x-spec-enum-id: 2d8d323e9cc0044b
+ x-spec-enum-id: 4b8815b179aa7216
enum:
- alibabacloud
- aws
@@ -2932,6 +2951,7 @@ paths:
- kubernetes
- m365
- mongodbatlas
+ - openstack
- oraclecloud
description: |-
* `aws` - AWS
@@ -2945,13 +2965,14 @@ paths:
* `oraclecloud` - Oracle Cloud Infrastructure
* `alibabacloud` - Alibaba Cloud
* `cloudflare` - Cloudflare
+ * `openstack` - OpenStack
- in: query
name: filter[provider_type__in]
schema:
type: array
items:
type: string
- x-spec-enum-id: 2d8d323e9cc0044b
+ x-spec-enum-id: 4b8815b179aa7216
enum:
- alibabacloud
- aws
@@ -2963,6 +2984,7 @@ paths:
- kubernetes
- m365
- mongodbatlas
+ - openstack
- oraclecloud
description: |-
Multiple values may be separated by commas.
@@ -2978,6 +3000,7 @@ paths:
* `oraclecloud` - Oracle Cloud Infrastructure
* `alibabacloud` - Alibaba Cloud
* `cloudflare` - Cloudflare
+ * `openstack` - OpenStack
explode: false
style: form
- in: query
@@ -3404,7 +3427,7 @@ paths:
name: filter[provider_type]
schema:
type: string
- x-spec-enum-id: 2d8d323e9cc0044b
+ x-spec-enum-id: 4b8815b179aa7216
enum:
- alibabacloud
- aws
@@ -3416,6 +3439,7 @@ paths:
- kubernetes
- m365
- mongodbatlas
+ - openstack
- oraclecloud
description: |-
* `aws` - AWS
@@ -3429,13 +3453,14 @@ paths:
* `oraclecloud` - Oracle Cloud Infrastructure
* `alibabacloud` - Alibaba Cloud
* `cloudflare` - Cloudflare
+ * `openstack` - OpenStack
- in: query
name: filter[provider_type__in]
schema:
type: array
items:
type: string
- x-spec-enum-id: 2d8d323e9cc0044b
+ x-spec-enum-id: 4b8815b179aa7216
enum:
- alibabacloud
- aws
@@ -3447,6 +3472,7 @@ paths:
- kubernetes
- m365
- mongodbatlas
+ - openstack
- oraclecloud
description: |-
Multiple values may be separated by commas.
@@ -3462,6 +3488,7 @@ paths:
* `oraclecloud` - Oracle Cloud Infrastructure
* `alibabacloud` - Alibaba Cloud
* `cloudflare` - Cloudflare
+ * `openstack` - OpenStack
explode: false
style: form
- in: query
@@ -5229,7 +5256,7 @@ paths:
name: filter[provider_type]
schema:
type: string
- x-spec-enum-id: 2d8d323e9cc0044b
+ x-spec-enum-id: 4b8815b179aa7216
enum:
- alibabacloud
- aws
@@ -5241,6 +5268,7 @@ paths:
- kubernetes
- m365
- mongodbatlas
+ - openstack
- oraclecloud
description: |-
* `aws` - AWS
@@ -5254,13 +5282,14 @@ paths:
* `oraclecloud` - Oracle Cloud Infrastructure
* `alibabacloud` - Alibaba Cloud
* `cloudflare` - Cloudflare
+ * `openstack` - OpenStack
- in: query
name: filter[provider_type__in]
schema:
type: array
items:
type: string
- x-spec-enum-id: 2d8d323e9cc0044b
+ x-spec-enum-id: 4b8815b179aa7216
enum:
- alibabacloud
- aws
@@ -5272,6 +5301,7 @@ paths:
- kubernetes
- m365
- mongodbatlas
+ - openstack
- oraclecloud
description: |-
Multiple values may be separated by commas.
@@ -5287,6 +5317,7 @@ paths:
* `oraclecloud` - Oracle Cloud Infrastructure
* `alibabacloud` - Alibaba Cloud
* `cloudflare` - Cloudflare
+ * `openstack` - OpenStack
explode: false
style: form
- name: filter[search]
@@ -5392,7 +5423,7 @@ paths:
name: filter[provider_type]
schema:
type: string
- x-spec-enum-id: 2d8d323e9cc0044b
+ x-spec-enum-id: 4b8815b179aa7216
enum:
- alibabacloud
- aws
@@ -5404,6 +5435,7 @@ paths:
- kubernetes
- m365
- mongodbatlas
+ - openstack
- oraclecloud
description: |-
* `aws` - AWS
@@ -5417,13 +5449,14 @@ paths:
* `oraclecloud` - Oracle Cloud Infrastructure
* `alibabacloud` - Alibaba Cloud
* `cloudflare` - Cloudflare
+ * `openstack` - OpenStack
- in: query
name: filter[provider_type__in]
schema:
type: array
items:
type: string
- x-spec-enum-id: 2d8d323e9cc0044b
+ x-spec-enum-id: 4b8815b179aa7216
enum:
- alibabacloud
- aws
@@ -5435,6 +5468,7 @@ paths:
- kubernetes
- m365
- mongodbatlas
+ - openstack
- oraclecloud
description: |-
Multiple values may be separated by commas.
@@ -5450,6 +5484,7 @@ paths:
* `oraclecloud` - Oracle Cloud Infrastructure
* `alibabacloud` - Alibaba Cloud
* `cloudflare` - Cloudflare
+ * `openstack` - OpenStack
explode: false
style: form
- name: filter[search]
@@ -5556,6 +5591,7 @@ paths:
- kubernetes
- m365
- mongodbatlas
+ - openstack
- oraclecloud
description: |-
* `aws` - AWS
@@ -5569,6 +5605,7 @@ paths:
* `oraclecloud` - Oracle Cloud Infrastructure
* `alibabacloud` - Alibaba Cloud
* `cloudflare` - Cloudflare
+ * `openstack` - OpenStack
- in: query
name: filter[provider_type__in]
schema:
@@ -5586,6 +5623,7 @@ paths:
- kubernetes
- m365
- mongodbatlas
+ - openstack
- oraclecloud
description: |-
Multiple values may be separated by commas.
@@ -5601,6 +5639,7 @@ paths:
* `oraclecloud` - Oracle Cloud Infrastructure
* `alibabacloud` - Alibaba Cloud
* `cloudflare` - Cloudflare
+ * `openstack` - OpenStack
explode: false
style: form
- name: filter[search]
@@ -5727,7 +5766,7 @@ paths:
name: filter[provider_type]
schema:
type: string
- x-spec-enum-id: 2d8d323e9cc0044b
+ x-spec-enum-id: 4b8815b179aa7216
enum:
- alibabacloud
- aws
@@ -5739,6 +5778,7 @@ paths:
- kubernetes
- m365
- mongodbatlas
+ - openstack
- oraclecloud
description: |-
* `aws` - AWS
@@ -5752,13 +5792,14 @@ paths:
* `oraclecloud` - Oracle Cloud Infrastructure
* `alibabacloud` - Alibaba Cloud
* `cloudflare` - Cloudflare
+ * `openstack` - OpenStack
- in: query
name: filter[provider_type__in]
schema:
type: array
items:
type: string
- x-spec-enum-id: 2d8d323e9cc0044b
+ x-spec-enum-id: 4b8815b179aa7216
enum:
- alibabacloud
- aws
@@ -5770,6 +5811,7 @@ paths:
- kubernetes
- m365
- mongodbatlas
+ - openstack
- oraclecloud
description: |-
Multiple values may be separated by commas.
@@ -5785,6 +5827,7 @@ paths:
* `oraclecloud` - Oracle Cloud Infrastructure
* `alibabacloud` - Alibaba Cloud
* `cloudflare` - Cloudflare
+ * `openstack` - OpenStack
explode: false
style: form
- in: query
@@ -5924,7 +5967,7 @@ paths:
name: filter[provider_type]
schema:
type: string
- x-spec-enum-id: 2d8d323e9cc0044b
+ x-spec-enum-id: 4b8815b179aa7216
enum:
- alibabacloud
- aws
@@ -5936,6 +5979,7 @@ paths:
- kubernetes
- m365
- mongodbatlas
+ - openstack
- oraclecloud
description: |-
* `aws` - AWS
@@ -5949,13 +5993,14 @@ paths:
* `oraclecloud` - Oracle Cloud Infrastructure
* `alibabacloud` - Alibaba Cloud
* `cloudflare` - Cloudflare
+ * `openstack` - OpenStack
- in: query
name: filter[provider_type__in]
schema:
type: array
items:
type: string
- x-spec-enum-id: 2d8d323e9cc0044b
+ x-spec-enum-id: 4b8815b179aa7216
enum:
- alibabacloud
- aws
@@ -5967,6 +6012,7 @@ paths:
- kubernetes
- m365
- mongodbatlas
+ - openstack
- oraclecloud
description: |-
Multiple values may be separated by commas.
@@ -5982,6 +6028,7 @@ paths:
* `oraclecloud` - Oracle Cloud Infrastructure
* `alibabacloud` - Alibaba Cloud
* `cloudflare` - Cloudflare
+ * `openstack` - OpenStack
explode: false
style: form
- in: query
@@ -6127,6 +6174,7 @@ paths:
- kubernetes
- m365
- mongodbatlas
+ - openstack
- oraclecloud
description: |-
* `aws` - AWS
@@ -6140,6 +6188,7 @@ paths:
* `oraclecloud` - Oracle Cloud Infrastructure
* `alibabacloud` - Alibaba Cloud
* `cloudflare` - Cloudflare
+ * `openstack` - OpenStack
- in: query
name: filter[provider_type__in]
schema:
@@ -6157,6 +6206,7 @@ paths:
- kubernetes
- m365
- mongodbatlas
+ - openstack
- oraclecloud
description: |-
Multiple values may be separated by commas.
@@ -6172,6 +6222,7 @@ paths:
* `oraclecloud` - Oracle Cloud Infrastructure
* `alibabacloud` - Alibaba Cloud
* `cloudflare` - Cloudflare
+ * `openstack` - OpenStack
explode: false
style: form
- name: filter[search]
@@ -6347,7 +6398,7 @@ paths:
name: filter[provider_type]
schema:
type: string
- x-spec-enum-id: 2d8d323e9cc0044b
+ x-spec-enum-id: 4b8815b179aa7216
enum:
- alibabacloud
- aws
@@ -6359,6 +6410,7 @@ paths:
- kubernetes
- m365
- mongodbatlas
+ - openstack
- oraclecloud
description: |-
* `aws` - AWS
@@ -6372,13 +6424,14 @@ paths:
* `oraclecloud` - Oracle Cloud Infrastructure
* `alibabacloud` - Alibaba Cloud
* `cloudflare` - Cloudflare
+ * `openstack` - OpenStack
- in: query
name: filter[provider_type__in]
schema:
type: array
items:
type: string
- x-spec-enum-id: 2d8d323e9cc0044b
+ x-spec-enum-id: 4b8815b179aa7216
enum:
- alibabacloud
- aws
@@ -6390,6 +6443,7 @@ paths:
- kubernetes
- m365
- mongodbatlas
+ - openstack
- oraclecloud
description: |-
Multiple values may be separated by commas.
@@ -6405,6 +6459,7 @@ paths:
* `oraclecloud` - Oracle Cloud Infrastructure
* `alibabacloud` - Alibaba Cloud
* `cloudflare` - Cloudflare
+ * `openstack` - OpenStack
explode: false
style: form
- in: query
@@ -6509,7 +6564,7 @@ paths:
name: filter[provider_type]
schema:
type: string
- x-spec-enum-id: 2d8d323e9cc0044b
+ x-spec-enum-id: 4b8815b179aa7216
enum:
- alibabacloud
- aws
@@ -6521,6 +6576,7 @@ paths:
- kubernetes
- m365
- mongodbatlas
+ - openstack
- oraclecloud
description: |-
* `aws` - AWS
@@ -6534,13 +6590,14 @@ paths:
* `oraclecloud` - Oracle Cloud Infrastructure
* `alibabacloud` - Alibaba Cloud
* `cloudflare` - Cloudflare
+ * `openstack` - OpenStack
- in: query
name: filter[provider_type__in]
schema:
type: array
items:
type: string
- x-spec-enum-id: 2d8d323e9cc0044b
+ x-spec-enum-id: 4b8815b179aa7216
enum:
- alibabacloud
- aws
@@ -6552,6 +6609,7 @@ paths:
- kubernetes
- m365
- mongodbatlas
+ - openstack
- oraclecloud
description: |-
Multiple values may be separated by commas.
@@ -6567,6 +6625,7 @@ paths:
* `oraclecloud` - Oracle Cloud Infrastructure
* `alibabacloud` - Alibaba Cloud
* `cloudflare` - Cloudflare
+ * `openstack` - OpenStack
explode: false
style: form
- in: query
@@ -6695,7 +6754,7 @@ paths:
name: filter[provider_type]
schema:
type: string
- x-spec-enum-id: 2d8d323e9cc0044b
+ x-spec-enum-id: 4b8815b179aa7216
enum:
- alibabacloud
- aws
@@ -6707,6 +6766,7 @@ paths:
- kubernetes
- m365
- mongodbatlas
+ - openstack
- oraclecloud
description: |-
* `aws` - AWS
@@ -6720,13 +6780,14 @@ paths:
* `oraclecloud` - Oracle Cloud Infrastructure
* `alibabacloud` - Alibaba Cloud
* `cloudflare` - Cloudflare
+ * `openstack` - OpenStack
- in: query
name: filter[provider_type__in]
schema:
type: array
items:
type: string
- x-spec-enum-id: 2d8d323e9cc0044b
+ x-spec-enum-id: 4b8815b179aa7216
enum:
- alibabacloud
- aws
@@ -6738,6 +6799,7 @@ paths:
- kubernetes
- m365
- mongodbatlas
+ - openstack
- oraclecloud
description: |-
Multiple values may be separated by commas.
@@ -6753,6 +6815,7 @@ paths:
* `oraclecloud` - Oracle Cloud Infrastructure
* `alibabacloud` - Alibaba Cloud
* `cloudflare` - Cloudflare
+ * `openstack` - OpenStack
explode: false
style: form
- in: query
@@ -7522,7 +7585,7 @@ paths:
name: filter[provider]
schema:
type: string
- x-spec-enum-id: 2d8d323e9cc0044b
+ x-spec-enum-id: 4b8815b179aa7216
enum:
- alibabacloud
- aws
@@ -7534,6 +7597,7 @@ paths:
- kubernetes
- m365
- mongodbatlas
+ - openstack
- oraclecloud
description: |-
* `aws` - AWS
@@ -7547,13 +7611,14 @@ paths:
* `oraclecloud` - Oracle Cloud Infrastructure
* `alibabacloud` - Alibaba Cloud
* `cloudflare` - Cloudflare
+ * `openstack` - OpenStack
- in: query
name: filter[provider__in]
schema:
type: array
items:
type: string
- x-spec-enum-id: 2d8d323e9cc0044b
+ x-spec-enum-id: 4b8815b179aa7216
enum:
- alibabacloud
- aws
@@ -7565,6 +7630,7 @@ paths:
- kubernetes
- m365
- mongodbatlas
+ - openstack
- oraclecloud
description: |-
Multiple values may be separated by commas.
@@ -7580,13 +7646,14 @@ paths:
* `oraclecloud` - Oracle Cloud Infrastructure
* `alibabacloud` - Alibaba Cloud
* `cloudflare` - Cloudflare
+ * `openstack` - OpenStack
explode: false
style: form
- in: query
name: filter[provider_type]
schema:
type: string
- x-spec-enum-id: 2d8d323e9cc0044b
+ x-spec-enum-id: 4b8815b179aa7216
enum:
- alibabacloud
- aws
@@ -7598,6 +7665,7 @@ paths:
- kubernetes
- m365
- mongodbatlas
+ - openstack
- oraclecloud
description: |-
* `aws` - AWS
@@ -7611,13 +7679,14 @@ paths:
* `oraclecloud` - Oracle Cloud Infrastructure
* `alibabacloud` - Alibaba Cloud
* `cloudflare` - Cloudflare
+ * `openstack` - OpenStack
- in: query
name: filter[provider_type__in]
schema:
type: array
items:
type: string
- x-spec-enum-id: 2d8d323e9cc0044b
+ x-spec-enum-id: 4b8815b179aa7216
enum:
- alibabacloud
- aws
@@ -7629,6 +7698,7 @@ paths:
- kubernetes
- m365
- mongodbatlas
+ - openstack
- oraclecloud
description: |-
Multiple values may be separated by commas.
@@ -7644,6 +7714,7 @@ paths:
* `oraclecloud` - Oracle Cloud Infrastructure
* `alibabacloud` - Alibaba Cloud
* `cloudflare` - Cloudflare
+ * `openstack` - OpenStack
explode: false
style: form
- name: filter[search]
@@ -8273,7 +8344,7 @@ paths:
name: filter[provider_type]
schema:
type: string
- x-spec-enum-id: 2d8d323e9cc0044b
+ x-spec-enum-id: 4b8815b179aa7216
enum:
- alibabacloud
- aws
@@ -8285,6 +8356,7 @@ paths:
- kubernetes
- m365
- mongodbatlas
+ - openstack
- oraclecloud
description: |-
* `aws` - AWS
@@ -8298,13 +8370,14 @@ paths:
* `oraclecloud` - Oracle Cloud Infrastructure
* `alibabacloud` - Alibaba Cloud
* `cloudflare` - Cloudflare
+ * `openstack` - OpenStack
- in: query
name: filter[provider_type__in]
schema:
type: array
items:
type: string
- x-spec-enum-id: 2d8d323e9cc0044b
+ x-spec-enum-id: 4b8815b179aa7216
enum:
- alibabacloud
- aws
@@ -8316,6 +8389,7 @@ paths:
- kubernetes
- m365
- mongodbatlas
+ - openstack
- oraclecloud
description: |-
Multiple values may be separated by commas.
@@ -8331,6 +8405,7 @@ paths:
* `oraclecloud` - Oracle Cloud Infrastructure
* `alibabacloud` - Alibaba Cloud
* `cloudflare` - Cloudflare
+ * `openstack` - OpenStack
explode: false
style: form
- in: query
@@ -8775,7 +8850,7 @@ paths:
name: filter[provider_type]
schema:
type: string
- x-spec-enum-id: 2d8d323e9cc0044b
+ x-spec-enum-id: 4b8815b179aa7216
enum:
- alibabacloud
- aws
@@ -8787,6 +8862,7 @@ paths:
- kubernetes
- m365
- mongodbatlas
+ - openstack
- oraclecloud
description: |-
* `aws` - AWS
@@ -8800,13 +8876,14 @@ paths:
* `oraclecloud` - Oracle Cloud Infrastructure
* `alibabacloud` - Alibaba Cloud
* `cloudflare` - Cloudflare
+ * `openstack` - OpenStack
- in: query
name: filter[provider_type__in]
schema:
type: array
items:
type: string
- x-spec-enum-id: 2d8d323e9cc0044b
+ x-spec-enum-id: 4b8815b179aa7216
enum:
- alibabacloud
- aws
@@ -8818,6 +8895,7 @@ paths:
- kubernetes
- m365
- mongodbatlas
+ - openstack
- oraclecloud
description: |-
Multiple values may be separated by commas.
@@ -8833,6 +8911,7 @@ paths:
* `oraclecloud` - Oracle Cloud Infrastructure
* `alibabacloud` - Alibaba Cloud
* `cloudflare` - Cloudflare
+ * `openstack` - OpenStack
explode: false
style: form
- in: query
@@ -9090,7 +9169,7 @@ paths:
name: filter[provider_type]
schema:
type: string
- x-spec-enum-id: 2d8d323e9cc0044b
+ x-spec-enum-id: 4b8815b179aa7216
enum:
- alibabacloud
- aws
@@ -9102,6 +9181,7 @@ paths:
- kubernetes
- m365
- mongodbatlas
+ - openstack
- oraclecloud
description: |-
* `aws` - AWS
@@ -9115,13 +9195,14 @@ paths:
* `oraclecloud` - Oracle Cloud Infrastructure
* `alibabacloud` - Alibaba Cloud
* `cloudflare` - Cloudflare
+ * `openstack` - OpenStack
- in: query
name: filter[provider_type__in]
schema:
type: array
items:
type: string
- x-spec-enum-id: 2d8d323e9cc0044b
+ x-spec-enum-id: 4b8815b179aa7216
enum:
- alibabacloud
- aws
@@ -9133,6 +9214,7 @@ paths:
- kubernetes
- m365
- mongodbatlas
+ - openstack
- oraclecloud
description: |-
Multiple values may be separated by commas.
@@ -9148,6 +9230,7 @@ paths:
* `oraclecloud` - Oracle Cloud Infrastructure
* `alibabacloud` - Alibaba Cloud
* `cloudflare` - Cloudflare
+ * `openstack` - OpenStack
explode: false
style: form
- in: query
@@ -9411,7 +9494,7 @@ paths:
name: filter[provider_type]
schema:
type: string
- x-spec-enum-id: 2d8d323e9cc0044b
+ x-spec-enum-id: 4b8815b179aa7216
enum:
- alibabacloud
- aws
@@ -9423,6 +9506,7 @@ paths:
- kubernetes
- m365
- mongodbatlas
+ - openstack
- oraclecloud
description: |-
* `aws` - AWS
@@ -9436,13 +9520,14 @@ paths:
* `oraclecloud` - Oracle Cloud Infrastructure
* `alibabacloud` - Alibaba Cloud
* `cloudflare` - Cloudflare
+ * `openstack` - OpenStack
- in: query
name: filter[provider_type__in]
schema:
type: array
items:
type: string
- x-spec-enum-id: 2d8d323e9cc0044b
+ x-spec-enum-id: 4b8815b179aa7216
enum:
- alibabacloud
- aws
@@ -9454,6 +9539,7 @@ paths:
- kubernetes
- m365
- mongodbatlas
+ - openstack
- oraclecloud
description: |-
Multiple values may be separated by commas.
@@ -9469,6 +9555,7 @@ paths:
* `oraclecloud` - Oracle Cloud Infrastructure
* `alibabacloud` - Alibaba Cloud
* `cloudflare` - Cloudflare
+ * `openstack` - OpenStack
explode: false
style: form
- in: query
@@ -10266,7 +10353,7 @@ paths:
name: filter[provider_type]
schema:
type: string
- x-spec-enum-id: 2d8d323e9cc0044b
+ x-spec-enum-id: 4b8815b179aa7216
enum:
- alibabacloud
- aws
@@ -10278,6 +10365,7 @@ paths:
- kubernetes
- m365
- mongodbatlas
+ - openstack
- oraclecloud
description: |-
* `aws` - AWS
@@ -10291,13 +10379,14 @@ paths:
* `oraclecloud` - Oracle Cloud Infrastructure
* `alibabacloud` - Alibaba Cloud
* `cloudflare` - Cloudflare
+ * `openstack` - OpenStack
- in: query
name: filter[provider_type__in]
schema:
type: array
items:
type: string
- x-spec-enum-id: 2d8d323e9cc0044b
+ x-spec-enum-id: 4b8815b179aa7216
enum:
- alibabacloud
- aws
@@ -10309,6 +10398,7 @@ paths:
- kubernetes
- m365
- mongodbatlas
+ - openstack
- oraclecloud
description: |-
Multiple values may be separated by commas.
@@ -10324,6 +10414,7 @@ paths:
* `oraclecloud` - Oracle Cloud Infrastructure
* `alibabacloud` - Alibaba Cloud
* `cloudflare` - Cloudflare
+ * `openstack` - OpenStack
explode: false
style: form
- in: query
@@ -10659,6 +10750,72 @@ paths:
description: CSV file containing the compliance report
'404':
description: Compliance report not found
+ /api/v1/scans/{id}/csa:
+ get:
+ operationId: scans_csa_retrieve
+ description: Download CSA Cloud Controls Matrix (CCM) v4.0 compliance report
+ as a PDF file.
+ summary: Retrieve CSA CCM compliance report
+ parameters:
+ - in: query
+ name: fields[scans]
+ schema:
+ type: array
+ items:
+ type: string
+ enum:
+ - name
+ - trigger
+ - state
+ - unique_resource_count
+ - progress
+ - duration
+ - provider
+ - task
+ - inserted_at
+ - started_at
+ - completed_at
+ - scheduled_at
+ - next_scan_at
+ - processor
+ - url
+ description: endpoint return only specific fields in the response on a per-type
+ basis by including a fields[TYPE] query parameter.
+ explode: false
+ - in: path
+ name: id
+ schema:
+ type: string
+ format: uuid
+ description: A UUID string identifying this scan.
+ required: true
+ - in: query
+ name: include
+ schema:
+ type: array
+ items:
+ type: string
+ enum:
+ - provider
+ description: include query parameter to allow the client to customize which
+ related resources should be returned.
+ explode: false
+ tags:
+ - Scan
+ security:
+ - JWT or API Key: []
+ responses:
+ '200':
+ description: PDF file containing the CSA CCM compliance report
+ '202':
+ description: The task is in progress
+ '401':
+ description: API key missing or user not Authenticated
+ '403':
+ description: There is a problem with credentials
+ '404':
+ description: The scan has no CSA CCM reports, or the CSA CCM report generation
+ task has not started yet
/api/v1/scans/{id}/ens:
get:
operationId: scans_ens_retrieve
@@ -12438,8 +12595,14 @@ components:
type: string
name:
type: string
+ short_description:
+ type: string
description:
type: string
+ attribution:
+ allOf:
+ - $ref: '#/components/schemas/AttackPathsQueryAttribution'
+ nullable: true
provider:
type: string
parameters:
@@ -12449,9 +12612,35 @@ components:
required:
- id
- name
+ - short_description
- description
- provider
- parameters
+ AttackPathsQueryAttribution:
+ type: object
+ required:
+ - type
+ - id
+ additionalProperties: false
+ properties:
+ type:
+ type: string
+ description: The [type](https://jsonapi.org/format/#document-resource-object-identification)
+ member is used to describe resource objects that share common attributes
+ and relationships.
+ enum:
+ - attack-paths-query-attributions
+ id: {}
+ attributes:
+ type: object
+ properties:
+ text:
+ type: string
+ link:
+ type: string
+ required:
+ - text
+ - link
AttackPathsQueryParameter:
type: object
required:
@@ -12617,6 +12806,8 @@ components:
type: integer
maximum: 2147483647
minimum: -2147483648
+ graph_data_ready:
+ type: boolean
provider_alias:
type: string
readOnly: true
@@ -17316,6 +17507,20 @@ components:
required:
- api_key
- api_email
+ - type: object
+ title: OpenStack clouds.yaml Credentials
+ properties:
+ clouds_yaml_content:
+ type: string
+ description: The full content of a clouds.yaml configuration
+ file.
+ clouds_yaml_cloud:
+ type: string
+ description: The name of the cloud to use from the clouds.yaml
+ file.
+ required:
+ - clouds_yaml_content
+ - clouds_yaml_cloud
writeOnly: true
required:
- secret
@@ -18315,6 +18520,7 @@ components:
- oraclecloud
- alibabacloud
- cloudflare
+ - openstack
type: string
description: |-
* `aws` - AWS
@@ -18328,7 +18534,8 @@ components:
* `oraclecloud` - Oracle Cloud Infrastructure
* `alibabacloud` - Alibaba Cloud
* `cloudflare` - Cloudflare
- x-spec-enum-id: 2d8d323e9cc0044b
+ * `openstack` - OpenStack
+ x-spec-enum-id: 4b8815b179aa7216
uid:
type: string
title: Unique identifier for the provider, set by the provider
@@ -18445,8 +18652,9 @@ components:
- oraclecloud
- alibabacloud
- cloudflare
+ - openstack
type: string
- x-spec-enum-id: 2d8d323e9cc0044b
+ x-spec-enum-id: 4b8815b179aa7216
description: |-
Type of provider to create.
@@ -18461,6 +18669,7 @@ components:
* `oraclecloud` - Oracle Cloud Infrastructure
* `alibabacloud` - Alibaba Cloud
* `cloudflare` - Cloudflare
+ * `openstack` - OpenStack
uid:
type: string
title: Unique identifier for the provider, set by the provider
@@ -18509,8 +18718,9 @@ components:
- oraclecloud
- alibabacloud
- cloudflare
+ - openstack
type: string
- x-spec-enum-id: 2d8d323e9cc0044b
+ x-spec-enum-id: 4b8815b179aa7216
description: |-
Type of provider to create.
@@ -18525,6 +18735,7 @@ components:
* `oraclecloud` - Oracle Cloud Infrastructure
* `alibabacloud` - Alibaba Cloud
* `cloudflare` - Cloudflare
+ * `openstack` - OpenStack
uid:
type: string
minLength: 3
@@ -19346,6 +19557,19 @@ components:
required:
- api_key
- api_email
+ - type: object
+ title: OpenStack clouds.yaml Credentials
+ properties:
+ clouds_yaml_content:
+ type: string
+ description: The full content of a clouds.yaml configuration file.
+ clouds_yaml_cloud:
+ type: string
+ description: The name of the cloud to use from the clouds.yaml
+ file.
+ required:
+ - clouds_yaml_content
+ - clouds_yaml_cloud
writeOnly: true
required:
- secret_type
@@ -19732,6 +19956,20 @@ components:
required:
- api_key
- api_email
+ - type: object
+ title: OpenStack clouds.yaml Credentials
+ properties:
+ clouds_yaml_content:
+ type: string
+ description: The full content of a clouds.yaml configuration
+ file.
+ clouds_yaml_cloud:
+ type: string
+ description: The name of the cloud to use from the clouds.yaml
+ file.
+ required:
+ - clouds_yaml_content
+ - clouds_yaml_cloud
writeOnly: true
required:
- secret_type
@@ -20130,6 +20368,19 @@ components:
required:
- api_key
- api_email
+ - type: object
+ title: OpenStack clouds.yaml Credentials
+ properties:
+ clouds_yaml_content:
+ type: string
+ description: The full content of a clouds.yaml configuration file.
+ clouds_yaml_cloud:
+ type: string
+ description: The name of the cloud to use from the clouds.yaml
+ file.
+ required:
+ - clouds_yaml_content
+ - clouds_yaml_cloud
writeOnly: true
required:
- secret
diff --git a/api/src/backend/api/tests/test_attack_paths.py b/api/src/backend/api/tests/test_attack_paths.py
index 2c4e1484f8..1b6e765164 100644
--- a/api/src/backend/api/tests/test_attack_paths.py
+++ b/api/src/backend/api/tests/test_attack_paths.py
@@ -83,12 +83,12 @@ def test_execute_attack_paths_query_serializes_graph(
definition = attack_paths_query_definition_factory(
id="aws-rds",
name="RDS",
+ short_description="Short desc",
description="",
cypher="MATCH (n) RETURN n",
parameters=[],
)
parameters = {"provider_uid": "123"}
- attack_paths_scan = SimpleNamespace(graph_database="tenant-db")
node = attack_paths_graph_stub_classes.Node(
element_id="node-1",
@@ -122,15 +122,17 @@ def test_execute_attack_paths_query_serializes_graph(
session_ctx.__enter__.return_value = session
session_ctx.__exit__.return_value = False
+ database_name = "db-tenant-test-tenant-id"
+
with patch(
"api.attack_paths.views_helpers.graph_database.get_session",
return_value=session_ctx,
) as mock_get_session:
result = views_helpers.execute_attack_paths_query(
- attack_paths_scan, definition, parameters
+ database_name, definition, parameters
)
- mock_get_session.assert_called_once_with("tenant-db")
+ mock_get_session.assert_called_once_with(database_name)
session.run.assert_called_once_with(definition.cypher, parameters)
assert result["nodes"][0]["id"] == "node-1"
assert result["nodes"][0]["properties"]["complex"]["items"][0] == "value"
@@ -143,11 +145,12 @@ def test_execute_attack_paths_query_wraps_graph_errors(
definition = attack_paths_query_definition_factory(
id="aws-rds",
name="RDS",
+ short_description="Short desc",
description="",
cypher="MATCH (n) RETURN n",
parameters=[],
)
- attack_paths_scan = SimpleNamespace(graph_database="tenant-db")
+ database_name = "db-tenant-test-tenant-id"
parameters = {"provider_uid": "123"}
class ExplodingContext:
@@ -166,7 +169,7 @@ def test_execute_attack_paths_query_wraps_graph_errors(
):
with pytest.raises(APIException):
views_helpers.execute_attack_paths_query(
- attack_paths_scan, definition, parameters
+ database_name, definition, parameters
)
mock_logger.error.assert_called_once()
diff --git a/api/src/backend/api/tests/test_utils.py b/api/src/backend/api/tests/test_utils.py
index 56f98a5401..236cbf87a2 100644
--- a/api/src/backend/api/tests/test_utils.py
+++ b/api/src/backend/api/tests/test_utils.py
@@ -27,6 +27,7 @@ from prowler.providers.iac.iac_provider import IacProvider
from prowler.providers.kubernetes.kubernetes_provider import KubernetesProvider
from prowler.providers.m365.m365_provider import M365Provider
from prowler.providers.mongodbatlas.mongodbatlas_provider import MongodbatlasProvider
+from prowler.providers.openstack.openstack_provider import OpenstackProvider
from prowler.providers.oraclecloud.oraclecloud_provider import OraclecloudProvider
@@ -120,6 +121,7 @@ class TestReturnProwlerProvider:
(Provider.ProviderChoices.IAC.value, IacProvider),
(Provider.ProviderChoices.ALIBABACLOUD.value, AlibabacloudProvider),
(Provider.ProviderChoices.CLOUDFLARE.value, CloudflareProvider),
+ (Provider.ProviderChoices.OPENSTACK.value, OpenstackProvider),
],
)
def test_return_prowler_provider(self, provider_type, expected_provider):
@@ -227,6 +229,10 @@ class TestGetProwlerProviderKwargs:
Provider.ProviderChoices.CLOUDFLARE.value,
{"filter_accounts": ["provider_uid"]},
),
+ (
+ Provider.ProviderChoices.OPENSTACK.value,
+ {},
+ ),
],
)
def test_get_prowler_provider_kwargs(self, provider_type, expected_extra_kwargs):
diff --git a/api/src/backend/api/tests/test_views.py b/api/src/backend/api/tests/test_views.py
index 4bb7509bc7..c7f2e5533d 100644
--- a/api/src/backend/api/tests/test_views.py
+++ b/api/src/backend/api/tests/test_views.py
@@ -1079,6 +1079,11 @@ class TestProviderViewSet:
[
{"provider": "aws", "uid": "111111111111", "alias": "test"},
{"provider": "gcp", "uid": "a12322-test54321", "alias": "test"},
+ {
+ "provider": "gcp",
+ "uid": "example.com:my-project-123456",
+ "alias": "legacy-gcp",
+ },
{
"provider": "kubernetes",
"uid": "kubernetes-test-123456789",
@@ -1179,6 +1184,11 @@ class TestProviderViewSet:
"uid": "a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4",
"alias": "Cloudflare Account",
},
+ {
+ "provider": "openstack",
+ "uid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
+ "alias": "OpenStack Project",
+ },
]
),
)
@@ -1198,6 +1208,11 @@ class TestProviderViewSet:
[
{"provider": "aws", "uid": "111111111111", "alias": "test"},
{"provider": "gcp", "uid": "a12322-test54321", "alias": "test"},
+ {
+ "provider": "gcp",
+ "uid": "example.com:my-project-123456",
+ "alias": "legacy-gcp",
+ },
{
"provider": "kubernetes",
"uid": "kubernetes-test-123456789",
@@ -1598,6 +1613,26 @@ class TestProviderViewSet:
"cloudflare-uid",
"uid",
),
+ # OpenStack UID validation - starts with special character
+ (
+ {
+ "provider": "openstack",
+ "uid": "-invalid-project",
+ "alias": "test",
+ },
+ "openstack-uid",
+ "uid",
+ ),
+ # OpenStack UID validation - too short (below min_length)
+ (
+ {
+ "provider": "openstack",
+ "uid": "ab",
+ "alias": "test",
+ },
+ "min_length",
+ "uid",
+ ),
]
),
)
@@ -1771,21 +1806,21 @@ class TestProviderViewSet:
(
"uid.icontains",
"1",
- 9,
+ 10,
),
("alias", "aws_testing_1", 1),
("alias.icontains", "aws", 2),
- ("inserted_at", TODAY, 10),
+ ("inserted_at", TODAY, 11),
(
"inserted_at.gte",
"2024-01-01",
- 10,
+ 11,
),
("inserted_at.lte", "2024-01-01", 0),
(
"updated_at.gte",
"2024-01-01",
- 10,
+ 11,
),
("updated_at.lte", "2024-01-01", 0),
]
@@ -2392,6 +2427,15 @@ class TestProviderSecretViewSet:
"api_email": "user@example.com",
},
),
+ # OpenStack with clouds.yaml content
+ (
+ Provider.ProviderChoices.OPENSTACK.value,
+ ProviderSecret.TypeChoices.STATIC,
+ {
+ "clouds_yaml_content": "clouds:\n mycloud:\n auth:\n auth_url: https://openstack.example.com:5000/v3\n",
+ "clouds_yaml_cloud": "mycloud",
+ },
+ ),
],
)
def test_provider_secrets_create_valid(
@@ -3830,6 +3874,7 @@ class TestAttackPathsScanViewSet:
AttackPathsQueryDefinition(
id="aws-rds",
name="RDS inventory",
+ short_description="List account RDS assets.",
description="List account RDS assets",
provider=provider.provider,
cypher="MATCH (n) RETURN n",
@@ -3887,11 +3932,12 @@ class TestAttackPathsScanViewSet:
attack_paths_scan = create_attack_paths_scan(
provider,
scan=scans_fixture[0],
- graph_database="tenant-db",
+ graph_data_ready=True,
)
query_definition = AttackPathsQueryDefinition(
id="aws-rds",
name="RDS inventory",
+ short_description="List account RDS assets.",
description="List account RDS assets",
provider=provider.provider,
cypher="MATCH (n) RETURN n",
@@ -3917,10 +3963,16 @@ class TestAttackPathsScanViewSet:
],
}
+ expected_db_name = f"db-tenant-{attack_paths_scan.provider.tenant_id}"
+
with (
patch(
"api.v1.views.get_query_by_id", return_value=query_definition
) as mock_get_query,
+ patch(
+ "api.v1.views.graph_database.get_database_name",
+ return_value=expected_db_name,
+ ) as mock_get_db_name,
patch(
"api.v1.views.attack_paths_views_helpers.prepare_query_parameters",
return_value=prepared_parameters,
@@ -3942,23 +3994,24 @@ class TestAttackPathsScanViewSet:
assert response.status_code == status.HTTP_200_OK
mock_get_query.assert_called_once_with("aws-rds")
+ mock_get_db_name.assert_called_once_with(attack_paths_scan.provider.tenant_id)
mock_prepare.assert_called_once_with(
query_definition,
{},
attack_paths_scan.provider.uid,
)
mock_execute.assert_called_once_with(
- attack_paths_scan,
+ expected_db_name,
query_definition,
prepared_parameters,
)
- mock_clear_cache.assert_called_once_with(attack_paths_scan.graph_database)
+ mock_clear_cache.assert_called_once_with(expected_db_name)
result = response.json()["data"]
attributes = result["attributes"]
assert attributes["nodes"] == graph_payload["nodes"]
assert attributes["relationships"] == graph_payload["relationships"]
- def test_run_attack_paths_query_requires_completed_scan(
+ def test_run_attack_paths_query_blocks_when_graph_data_not_ready(
self,
authenticated_client,
providers_fixture,
@@ -3970,6 +4023,7 @@ class TestAttackPathsScanViewSet:
provider,
scan=scans_fixture[0],
state=StateChoices.EXECUTING,
+ graph_data_ready=False,
)
response = authenticated_client.post(
@@ -3981,9 +4035,9 @@ class TestAttackPathsScanViewSet:
)
assert response.status_code == status.HTTP_400_BAD_REQUEST
- assert "must be completed" in response.json()["errors"][0]["detail"]
+ assert "not available" in response.json()["errors"][0]["detail"]
- def test_run_attack_paths_query_requires_graph_database(
+ def test_run_attack_paths_query_allows_executing_scan_when_graph_data_ready(
self,
authenticated_client,
providers_fixture,
@@ -3994,19 +4048,100 @@ class TestAttackPathsScanViewSet:
attack_paths_scan = create_attack_paths_scan(
provider,
scan=scans_fixture[0],
- graph_database=None,
+ state=StateChoices.EXECUTING,
+ graph_data_ready=True,
+ )
+ query_definition = AttackPathsQueryDefinition(
+ id="aws-test",
+ name="Test",
+ short_description="Test query.",
+ description="Test query",
+ provider=provider.provider,
+ cypher="MATCH (n) RETURN n",
+ parameters=[],
)
- response = authenticated_client.post(
- reverse(
- "attack-paths-scans-queries-run", kwargs={"pk": attack_paths_scan.id}
+ with (
+ patch("api.v1.views.get_query_by_id", return_value=query_definition),
+ patch(
+ "api.v1.views.attack_paths_views_helpers.prepare_query_parameters",
+ return_value={"provider_uid": provider.uid},
),
- data=self._run_payload(),
- content_type=API_JSON_CONTENT_TYPE,
+ patch(
+ "api.v1.views.attack_paths_views_helpers.execute_attack_paths_query",
+ return_value={
+ "nodes": [{"id": "n1", "labels": ["AWSAccount"], "properties": {}}],
+ "relationships": [],
+ },
+ ),
+ patch("api.v1.views.graph_database.clear_cache"),
+ patch(
+ "api.v1.views.graph_database.get_database_name", return_value="db-test"
+ ),
+ ):
+ response = authenticated_client.post(
+ reverse(
+ "attack-paths-scans-queries-run",
+ kwargs={"pk": attack_paths_scan.id},
+ ),
+ data=self._run_payload("aws-test"),
+ content_type=API_JSON_CONTENT_TYPE,
+ )
+
+ assert response.status_code == status.HTTP_200_OK
+
+ def test_run_attack_paths_query_allows_failed_scan_when_graph_data_ready(
+ self,
+ authenticated_client,
+ providers_fixture,
+ scans_fixture,
+ create_attack_paths_scan,
+ ):
+ provider = providers_fixture[0]
+ attack_paths_scan = create_attack_paths_scan(
+ provider,
+ scan=scans_fixture[0],
+ state=StateChoices.FAILED,
+ graph_data_ready=True,
+ )
+ query_definition = AttackPathsQueryDefinition(
+ id="aws-test",
+ name="Test",
+ short_description="Test query.",
+ description="Test query",
+ provider=provider.provider,
+ cypher="MATCH (n) RETURN n",
+ parameters=[],
)
- assert response.status_code == status.HTTP_500_INTERNAL_SERVER_ERROR
- assert "does not reference a graph database" in str(response.json())
+ with (
+ patch("api.v1.views.get_query_by_id", return_value=query_definition),
+ patch(
+ "api.v1.views.attack_paths_views_helpers.prepare_query_parameters",
+ return_value={"provider_uid": provider.uid},
+ ),
+ patch(
+ "api.v1.views.attack_paths_views_helpers.execute_attack_paths_query",
+ return_value={
+ "nodes": [{"id": "n1", "labels": ["AWSAccount"], "properties": {}}],
+ "relationships": [],
+ },
+ ),
+ patch("api.v1.views.graph_database.clear_cache"),
+ patch(
+ "api.v1.views.graph_database.get_database_name", return_value="db-test"
+ ),
+ ):
+ response = authenticated_client.post(
+ reverse(
+ "attack-paths-scans-queries-run",
+ kwargs={"pk": attack_paths_scan.id},
+ ),
+ data=self._run_payload("aws-test"),
+ content_type=API_JSON_CONTENT_TYPE,
+ )
+
+ assert response.status_code == status.HTTP_200_OK
def test_run_attack_paths_query_unknown_query(
self,
@@ -4019,6 +4154,7 @@ class TestAttackPathsScanViewSet:
attack_paths_scan = create_attack_paths_scan(
provider,
scan=scans_fixture[0],
+ graph_data_ready=True,
)
with patch("api.v1.views.get_query_by_id", return_value=None):
@@ -4045,10 +4181,12 @@ class TestAttackPathsScanViewSet:
attack_paths_scan = create_attack_paths_scan(
provider,
scan=scans_fixture[0],
+ graph_data_ready=True,
)
query_definition = AttackPathsQueryDefinition(
id="aws-empty",
name="empty",
+ short_description="",
description="",
provider=provider.provider,
cypher="MATCH (n) RETURN n",
@@ -10841,25 +10979,20 @@ class TestTenantFinishACSView:
assert "sso_saml_failed=true" in response.url
def test_dispatch_skips_role_mapping_when_single_manage_account_user(
- self, create_test_user, tenants_fixture, saml_setup, settings, monkeypatch
+ self,
+ create_test_user,
+ tenants_fixture,
+ admin_role_fixture,
+ saml_setup,
+ settings,
+ monkeypatch,
):
"""Test that role mapping is skipped when tenant has only one user with MANAGE_ACCOUNT role"""
monkeypatch.setenv("SAML_SSO_CALLBACK_URL", "http://localhost/sso-complete")
user = create_test_user
tenant = tenants_fixture[0]
- # Create a single role with manage_account=True for the user
- admin_role = Role.objects.using(MainRouter.admin_db).create(
- name="admin",
- tenant=tenant,
- manage_account=True,
- manage_users=True,
- manage_billing=True,
- manage_providers=True,
- manage_integrations=True,
- manage_scans=True,
- unlimited_visibility=True,
- )
+ admin_role = admin_role_fixture
UserRoleRelationship.objects.using(MainRouter.admin_db).create(
user=user, role=admin_role, tenant_id=tenant.id
)
@@ -10930,35 +11063,26 @@ class TestTenantFinishACSView:
.exists()
)
- def test_dispatch_applies_role_mapping_when_multiple_manage_account_users(
- self, create_test_user, tenants_fixture, saml_setup, settings, monkeypatch
+ def test_dispatch_skips_role_mapping_when_last_manage_account_user_maps_to_existing_role(
+ self,
+ create_test_user,
+ tenants_fixture,
+ admin_role_fixture,
+ roles_fixture,
+ saml_setup,
+ settings,
+ monkeypatch,
):
- """Test that role mapping is applied when tenant has multiple users with MANAGE_ACCOUNT role"""
+ """Test that role mapping is skipped when it would remove the last MANAGE_ACCOUNT user"""
monkeypatch.setenv("SAML_SSO_CALLBACK_URL", "http://localhost/sso-complete")
user = create_test_user
tenant = tenants_fixture[0]
- # Create a second user with manage_account=True
- second_admin = User.objects.using(MainRouter.admin_db).create(
- email="admin2@prowler.com", name="Second Admin"
- )
- admin_role = Role.objects.using(MainRouter.admin_db).create(
- name="admin",
- tenant=tenant,
- manage_account=True,
- manage_users=True,
- manage_billing=True,
- manage_providers=True,
- manage_integrations=True,
- manage_scans=True,
- unlimited_visibility=True,
- )
+ admin_role = admin_role_fixture
+ viewer_role = roles_fixture[3]
UserRoleRelationship.objects.using(MainRouter.admin_db).create(
user=user, role=admin_role, tenant_id=tenant.id
)
- UserRoleRelationship.objects.using(MainRouter.admin_db).create(
- user=second_admin, role=admin_role, tenant_id=tenant.id
- )
social_account = SocialAccount(
user=user,
@@ -10967,7 +11091,7 @@ class TestTenantFinishACSView:
"firstName": ["John"],
"lastName": ["Doe"],
"organization": ["testing_company"],
- "userType": ["viewer"], # This SHOULD be applied
+ "userType": [viewer_role.name],
},
)
@@ -11005,10 +11129,91 @@ class TestTenantFinishACSView:
assert response.status_code == 302
- # Verify the viewer role was created and assigned (role mapping was applied)
- viewer_role = Role.objects.using(MainRouter.admin_db).get(
- name="viewer", tenant=tenant
+ assert (
+ UserRoleRelationship.objects.using(MainRouter.admin_db)
+ .filter(user=user, role=admin_role, tenant_id=tenant.id)
+ .exists()
)
+ assert not (
+ UserRoleRelationship.objects.using(MainRouter.admin_db)
+ .filter(user=user, role=viewer_role, tenant_id=tenant.id)
+ .exists()
+ )
+
+ def test_dispatch_applies_role_mapping_when_multiple_manage_account_users(
+ self,
+ create_test_user,
+ tenants_fixture,
+ admin_role_fixture,
+ roles_fixture,
+ saml_setup,
+ settings,
+ monkeypatch,
+ ):
+ """Test that role mapping is applied when tenant has multiple users with MANAGE_ACCOUNT role"""
+ monkeypatch.setenv("SAML_SSO_CALLBACK_URL", "http://localhost/sso-complete")
+ user = create_test_user
+ tenant = tenants_fixture[0]
+
+ # Create a second user with manage_account=True
+ second_admin = User.objects.using(MainRouter.admin_db).create(
+ email="admin2@prowler.com", name="Second Admin"
+ )
+ admin_role = admin_role_fixture
+ viewer_role = roles_fixture[3]
+ UserRoleRelationship.objects.using(MainRouter.admin_db).create(
+ user=user, role=admin_role, tenant_id=tenant.id
+ )
+ UserRoleRelationship.objects.using(MainRouter.admin_db).create(
+ user=second_admin, role=admin_role, tenant_id=tenant.id
+ )
+
+ social_account = SocialAccount(
+ user=user,
+ provider="saml",
+ extra_data={
+ "firstName": ["John"],
+ "lastName": ["Doe"],
+ "organization": ["testing_company"],
+ "userType": [viewer_role.name], # This SHOULD be applied
+ },
+ )
+
+ request = RequestFactory().get(
+ reverse("saml_finish_acs", kwargs={"organization_slug": "testtenant"})
+ )
+ request.user = user
+ request.session = {}
+
+ with (
+ patch(
+ "allauth.socialaccount.providers.saml.views.get_app_or_404"
+ ) as mock_get_app_or_404,
+ patch(
+ "allauth.socialaccount.models.SocialApp.objects.get"
+ ) as mock_socialapp_get,
+ patch(
+ "allauth.socialaccount.models.SocialAccount.objects.get"
+ ) as mock_sa_get,
+ patch("api.models.SAMLDomainIndex.objects.get") as mock_saml_domain_get,
+ patch("api.models.SAMLConfiguration.objects.get") as mock_saml_config_get,
+ patch("api.models.User.objects.get") as mock_user_get,
+ ):
+ mock_get_app_or_404.return_value = MagicMock(
+ provider="saml", client_id="testtenant", name="Test App", settings={}
+ )
+ mock_sa_get.return_value = social_account
+ mock_socialapp_get.return_value = MagicMock(provider_id="saml")
+ mock_saml_domain_get.return_value = SimpleNamespace(tenant_id=tenant.id)
+ mock_saml_config_get.return_value = MagicMock()
+ mock_user_get.return_value = user
+
+ view = TenantFinishACSView.as_view()
+ response = view(request, organization_slug="testtenant")
+
+ assert response.status_code == 302
+
+ # Verify the viewer role was assigned (role mapping was applied)
assert (
UserRoleRelationship.objects.using(MainRouter.admin_db)
.filter(user=user, role=viewer_role, tenant_id=tenant.id)
@@ -11022,6 +11227,86 @@ class TestTenantFinishACSView:
.exists()
)
+ def test_dispatch_applies_role_mapping_for_non_admin_user_with_single_admin(
+ self,
+ create_test_user,
+ tenants_fixture,
+ admin_role_fixture,
+ roles_fixture,
+ saml_setup,
+ settings,
+ monkeypatch,
+ ):
+ """Test that role mapping is applied for a non-admin user when a single admin exists"""
+ monkeypatch.setenv("SAML_SSO_CALLBACK_URL", "http://localhost/sso-complete")
+ admin_user = create_test_user
+ tenant = tenants_fixture[0]
+ non_admin_user = User.objects.using(MainRouter.admin_db).create(
+ email="viewer@prowler.com", name="Viewer"
+ )
+
+ admin_role = admin_role_fixture
+ viewer_role = roles_fixture[3]
+ UserRoleRelationship.objects.using(MainRouter.admin_db).create(
+ user=admin_user, role=admin_role, tenant_id=tenant.id
+ )
+
+ social_account = SocialAccount(
+ user=non_admin_user,
+ provider="saml",
+ extra_data={
+ "firstName": ["Jane"],
+ "lastName": ["Doe"],
+ "organization": ["testing_company"],
+ "userType": [viewer_role.name],
+ },
+ )
+
+ request = RequestFactory().get(
+ reverse("saml_finish_acs", kwargs={"organization_slug": "testtenant"})
+ )
+ request.user = non_admin_user
+ request.session = {}
+
+ with (
+ patch(
+ "allauth.socialaccount.providers.saml.views.get_app_or_404"
+ ) as mock_get_app_or_404,
+ patch(
+ "allauth.socialaccount.models.SocialApp.objects.get"
+ ) as mock_socialapp_get,
+ patch(
+ "allauth.socialaccount.models.SocialAccount.objects.get"
+ ) as mock_sa_get,
+ patch("api.models.SAMLDomainIndex.objects.get") as mock_saml_domain_get,
+ patch("api.models.SAMLConfiguration.objects.get") as mock_saml_config_get,
+ patch("api.models.User.objects.get") as mock_user_get,
+ ):
+ mock_get_app_or_404.return_value = MagicMock(
+ provider="saml", client_id="testtenant", name="Test App", settings={}
+ )
+ mock_sa_get.return_value = social_account
+ mock_socialapp_get.return_value = MagicMock(provider_id="saml")
+ mock_saml_domain_get.return_value = SimpleNamespace(tenant_id=tenant.id)
+ mock_saml_config_get.return_value = MagicMock()
+ mock_user_get.return_value = non_admin_user
+
+ view = TenantFinishACSView.as_view()
+ response = view(request, organization_slug="testtenant")
+
+ assert response.status_code == 302
+
+ assert (
+ UserRoleRelationship.objects.using(MainRouter.admin_db)
+ .filter(user=non_admin_user, role=viewer_role, tenant_id=tenant.id)
+ .exists()
+ )
+ assert (
+ UserRoleRelationship.objects.using(MainRouter.admin_db)
+ .filter(user=admin_user, role=admin_role, tenant_id=tenant.id)
+ .exists()
+ )
+
@pytest.mark.django_db
class TestLighthouseConfigViewSet:
diff --git a/api/src/backend/api/utils.py b/api/src/backend/api/utils.py
index 343537efa9..355c3b6e03 100644
--- a/api/src/backend/api/utils.py
+++ b/api/src/backend/api/utils.py
@@ -33,6 +33,7 @@ if TYPE_CHECKING:
from prowler.providers.mongodbatlas.mongodbatlas_provider import (
MongodbatlasProvider,
)
+ from prowler.providers.openstack.openstack_provider import OpenstackProvider
from prowler.providers.oraclecloud.oraclecloud_provider import OraclecloudProvider
@@ -78,12 +79,14 @@ def return_prowler_provider(
AlibabacloudProvider
| AwsProvider
| AzureProvider
+ | CloudflareProvider
| GcpProvider
| GithubProvider
| IacProvider
| KubernetesProvider
| M365Provider
| MongodbatlasProvider
+ | OpenstackProvider
| OraclecloudProvider
):
"""Return the Prowler provider class based on the given provider type.
@@ -92,7 +95,7 @@ def return_prowler_provider(
provider (Provider): The provider object containing the provider type and associated secrets.
Returns:
- AlibabacloudProvider | AwsProvider | AzureProvider | CloudflareProvider | GcpProvider | GithubProvider | IacProvider | KubernetesProvider | M365Provider | MongodbatlasProvider | OraclecloudProvider: The corresponding provider class.
+ AlibabacloudProvider | AwsProvider | AzureProvider | CloudflareProvider | GcpProvider | GithubProvider | IacProvider | KubernetesProvider | M365Provider | MongodbatlasProvider | OpenstackProvider | OraclecloudProvider: The corresponding provider class.
Raises:
ValueError: If the provider type specified in `provider.provider` is not supported.
@@ -152,6 +155,10 @@ def return_prowler_provider(
)
prowler_provider = CloudflareProvider
+ case Provider.ProviderChoices.OPENSTACK.value:
+ from prowler.providers.openstack.openstack_provider import OpenstackProvider
+
+ prowler_provider = OpenstackProvider
case _:
raise ValueError(f"Provider type {provider.provider} not supported")
return prowler_provider
@@ -208,6 +215,12 @@ def get_prowler_provider_kwargs(
**prowler_provider_kwargs,
"filter_accounts": [provider.uid],
}
+ elif provider.provider == Provider.ProviderChoices.OPENSTACK.value:
+ # No extra kwargs needed: clouds_yaml_content and clouds_yaml_cloud from the
+ # secret are sufficient. Validating project_id (provider.uid) against the
+ # clouds.yaml is not feasible because not all auth methods include it and the
+ # Keystone API is unavailable on public clouds.
+ pass
if mutelist_processor:
mutelist_content = mutelist_processor.configuration.get("Mutelist", {})
@@ -232,6 +245,7 @@ def initialize_prowler_provider(
| KubernetesProvider
| M365Provider
| MongodbatlasProvider
+ | OpenstackProvider
| OraclecloudProvider
):
"""Initialize a Prowler provider instance based on the given provider type.
@@ -241,7 +255,7 @@ def initialize_prowler_provider(
mutelist_processor (Processor): The mutelist processor object containing the mutelist configuration.
Returns:
- AlibabacloudProvider | AwsProvider | AzureProvider | CloudflareProvider | GcpProvider | GithubProvider | IacProvider | KubernetesProvider | M365Provider | MongodbatlasProvider | OraclecloudProvider: An instance of the corresponding provider class
+ AlibabacloudProvider | AwsProvider | AzureProvider | CloudflareProvider | GcpProvider | GithubProvider | IacProvider | KubernetesProvider | M365Provider | MongodbatlasProvider | OpenstackProvider | OraclecloudProvider: An instance of the corresponding provider class
initialized with the provider's secrets.
"""
prowler_provider = return_prowler_provider(provider)
@@ -276,6 +290,13 @@ def prowler_provider_connection_test(provider: Provider) -> Connection:
if "access_token" in prowler_provider_kwargs:
iac_test_kwargs["access_token"] = prowler_provider_kwargs["access_token"]
return prowler_provider.test_connection(**iac_test_kwargs)
+ elif provider.provider == Provider.ProviderChoices.OPENSTACK.value:
+ openstack_kwargs = {
+ "clouds_yaml_content": prowler_provider_kwargs["clouds_yaml_content"],
+ "clouds_yaml_cloud": prowler_provider_kwargs["clouds_yaml_cloud"],
+ "raise_on_exception": False,
+ }
+ return prowler_provider.test_connection(**openstack_kwargs)
else:
return prowler_provider.test_connection(
**prowler_provider_kwargs,
diff --git a/api/src/backend/api/v1/serializer_utils/providers.py b/api/src/backend/api/v1/serializer_utils/providers.py
index 7b34b06d2b..83ea942793 100644
--- a/api/src/backend/api/v1/serializer_utils/providers.py
+++ b/api/src/backend/api/v1/serializer_utils/providers.py
@@ -373,6 +373,21 @@ from rest_framework_json_api import serializers
},
"required": ["api_key", "api_email"],
},
+ {
+ "type": "object",
+ "title": "OpenStack clouds.yaml Credentials",
+ "properties": {
+ "clouds_yaml_content": {
+ "type": "string",
+ "description": "The full content of a clouds.yaml configuration file.",
+ },
+ "clouds_yaml_cloud": {
+ "type": "string",
+ "description": "The name of the cloud to use from the clouds.yaml file.",
+ },
+ },
+ "required": ["clouds_yaml_content", "clouds_yaml_cloud"],
+ },
]
}
)
diff --git a/api/src/backend/api/v1/serializers.py b/api/src/backend/api/v1/serializers.py
index e2ae7fc8d2..8cb7ef49cb 100644
--- a/api/src/backend/api/v1/serializers.py
+++ b/api/src/backend/api/v1/serializers.py
@@ -1145,6 +1145,7 @@ class AttackPathsScanSerializer(RLSSerializer):
"id",
"state",
"progress",
+ "graph_data_ready",
"provider",
"provider_alias",
"provider_type",
@@ -1176,6 +1177,14 @@ class AttackPathsScanSerializer(RLSSerializer):
return provider.uid if provider else None
+class AttackPathsQueryAttributionSerializer(BaseSerializerV1):
+ text = serializers.CharField()
+ link = serializers.CharField()
+
+ class JSONAPIMeta:
+ resource_name = "attack-paths-query-attributions"
+
+
class AttackPathsQueryParameterSerializer(BaseSerializerV1):
name = serializers.CharField()
label = serializers.CharField()
@@ -1190,7 +1199,9 @@ class AttackPathsQueryParameterSerializer(BaseSerializerV1):
class AttackPathsQuerySerializer(BaseSerializerV1):
id = serializers.CharField()
name = serializers.CharField()
+ short_description = serializers.CharField()
description = serializers.CharField()
+ attribution = AttackPathsQueryAttributionSerializer(allow_null=True, required=False)
provider = serializers.CharField()
parameters = AttackPathsQueryParameterSerializer(many=True)
@@ -1515,6 +1526,8 @@ class BaseWriteProviderSecretSerializer(BaseWriteSerializer):
"or both 'api_key' and 'api_email'."
}
)
+ elif provider_type == Provider.ProviderChoices.OPENSTACK.value:
+ serializer = OpenStackCloudsYamlProviderSecret(data=secret)
else:
raise serializers.ValidationError(
{"provider": f"Provider type not supported {provider_type}"}
@@ -1681,6 +1694,14 @@ class CloudflareApiKeyProviderSecret(serializers.Serializer):
resource_name = "provider-secrets"
+class OpenStackCloudsYamlProviderSecret(serializers.Serializer):
+ clouds_yaml_content = serializers.CharField()
+ clouds_yaml_cloud = serializers.CharField()
+
+ class Meta:
+ resource_name = "provider-secrets"
+
+
class AlibabaCloudProviderSecret(serializers.Serializer):
access_key_id = serializers.CharField()
access_key_secret = serializers.CharField()
diff --git a/api/src/backend/api/v1/views.py b/api/src/backend/api/v1/views.py
index 7ddcfe2461..365b9c45e0 100644
--- a/api/src/backend/api/v1/views.py
+++ b/api/src/backend/api/v1/views.py
@@ -763,27 +763,40 @@ class TenantFinishACSView(FinishACSView):
.tenant
)
- # Check if tenant has only one user with MANAGE_ACCOUNT role
- users_with_manage_account = (
+ role_name = (
+ extra.get("userType", ["no_permissions"])[0].strip()
+ if extra.get("userType")
+ else "no_permissions"
+ )
+ role = (
+ Role.objects.using(MainRouter.admin_db)
+ .filter(name=role_name, tenant=tenant)
+ .first()
+ )
+
+ # Only skip mapping if it would remove the last MANAGE_ACCOUNT user
+ remaining_manage_account_users = (
UserRoleRelationship.objects.using(MainRouter.admin_db)
.filter(role__manage_account=True, tenant_id=tenant.id)
+ .exclude(user_id=user_id)
.values("user")
.distinct()
.count()
)
+ user_has_manage_account = (
+ UserRoleRelationship.objects.using(MainRouter.admin_db)
+ .filter(role__manage_account=True, tenant_id=tenant.id, user_id=user_id)
+ .exists()
+ )
+ role_manage_account = role.manage_account if role else False
+ would_remove_last_manage_account = (
+ user_has_manage_account
+ and remaining_manage_account_users == 0
+ and not role_manage_account
+ )
- # Only apply role mapping from userType if tenant does NOT have exactly one user with MANAGE_ACCOUNT
- if users_with_manage_account != 1:
- role_name = (
- extra.get("userType", ["no_permissions"])[0].strip()
- if extra.get("userType")
- else "no_permissions"
- )
- try:
- role = Role.objects.using(MainRouter.admin_db).get(
- name=role_name, tenant=tenant
- )
- except Role.DoesNotExist:
+ if not would_remove_last_manage_account:
+ if role is None:
role = Role.objects.using(MainRouter.admin_db).create(
name=role_name,
tenant=tenant,
@@ -1746,6 +1759,25 @@ class ProviderViewSet(DisablePaginationMixin, BaseRLSViewSet):
),
},
),
+ csa=extend_schema(
+ tags=["Scan"],
+ summary="Retrieve CSA CCM compliance report",
+ description="Download CSA Cloud Controls Matrix (CCM) v4.0 compliance report as a PDF file.",
+ request=None,
+ responses={
+ 200: OpenApiResponse(
+ description="PDF file containing the CSA CCM compliance report"
+ ),
+ 202: OpenApiResponse(description="The task is in progress"),
+ 401: OpenApiResponse(
+ description="API key missing or user not Authenticated"
+ ),
+ 403: OpenApiResponse(description="There is a problem with credentials"),
+ 404: OpenApiResponse(
+ description="The scan has no CSA CCM reports, or the CSA CCM report generation task has not started yet"
+ ),
+ },
+ ),
)
@method_decorator(CACHE_DECORATOR, name="list")
@method_decorator(CACHE_DECORATOR, name="retrieve")
@@ -1811,6 +1843,9 @@ class ScanViewSet(BaseRLSViewSet):
elif self.action == "nis2":
if hasattr(self, "response_serializer_class"):
return self.response_serializer_class
+ elif self.action == "csa":
+ if hasattr(self, "response_serializer_class"):
+ return self.response_serializer_class
return super().get_serializer_class()
def partial_update(self, request, *args, **kwargs):
@@ -2172,6 +2207,45 @@ class ScanViewSet(BaseRLSViewSet):
content, filename = loader
return self._serve_file(content, filename, "application/pdf")
+ @action(
+ detail=True,
+ methods=["get"],
+ url_name="csa",
+ )
+ def csa(self, request, pk=None):
+ scan = self.get_object()
+ running_resp = self._get_task_status(scan)
+ if running_resp:
+ return running_resp
+
+ if not scan.output_location:
+ return Response(
+ {
+ "detail": "The scan has no reports, or the CSA CCM report generation task has not started yet."
+ },
+ status=status.HTTP_404_NOT_FOUND,
+ )
+
+ if scan.output_location.startswith("s3://"):
+ bucket = env.str("DJANGO_OUTPUT_S3_AWS_OUTPUT_BUCKET", "")
+ key_prefix = scan.output_location.removeprefix(f"s3://{bucket}/")
+ prefix = os.path.join(
+ os.path.dirname(key_prefix),
+ "csa",
+ "*_csa_report.pdf",
+ )
+ loader = self._load_file(prefix, s3=True, bucket=bucket, list_objects=True)
+ else:
+ base = os.path.dirname(scan.output_location)
+ pattern = os.path.join(base, "csa", "*_csa_report.pdf")
+ loader = self._load_file(pattern, s3=False)
+
+ if isinstance(loader, Response):
+ return loader
+
+ content, filename = loader
+ return self._serve_file(content, filename, "application/pdf")
+
def create(self, request, *args, **kwargs):
input_serializer = self.get_serializer(data=request.data)
input_serializer.is_valid(raise_exception=True)
@@ -2408,22 +2482,13 @@ class AttackPathsScanViewSet(BaseRLSViewSet):
def run_attack_paths_query(self, request, pk=None):
attack_paths_scan = self.get_object()
- if attack_paths_scan.state != StateChoices.COMPLETED:
+ if not attack_paths_scan.graph_data_ready:
raise ValidationError(
{
- "detail": "The Attack Paths scan must be completed before running Attack Paths queries"
+ "detail": "Attack Paths data is not available for querying - a scan must complete at least once before queries can be run"
}
)
- if not attack_paths_scan.graph_database:
- logger.error(
- f"The Attack Paths Scan {attack_paths_scan.id} does not reference a graph database"
- )
- return Response(
- {"detail": "The Attack Paths scan does not reference a graph database"},
- status=status.HTTP_500_INTERNAL_SERVER_ERROR,
- )
-
payload = attack_paths_views_helpers.normalize_run_payload(request.data)
serializer = AttackPathsQueryRunRequestSerializer(data=payload)
serializer.is_valid(raise_exception=True)
@@ -2437,6 +2502,9 @@ class AttackPathsScanViewSet(BaseRLSViewSet):
{"id": "Unknown Attack Paths query for the selected provider"}
)
+ database_name = graph_database.get_database_name(
+ attack_paths_scan.provider.tenant_id
+ )
parameters = attack_paths_views_helpers.prepare_query_parameters(
query_definition,
serializer.validated_data.get("parameters", {}),
@@ -2444,9 +2512,9 @@ class AttackPathsScanViewSet(BaseRLSViewSet):
)
graph = attack_paths_views_helpers.execute_attack_paths_query(
- attack_paths_scan, query_definition, parameters
+ database_name, query_definition, parameters
)
- graph_database.clear_cache(attack_paths_scan.graph_database)
+ graph_database.clear_cache(database_name)
status_code = status.HTTP_200_OK
if not graph.get("nodes"):
diff --git a/api/src/backend/config/django/testing.py b/api/src/backend/config/django/testing.py
index 5289f067fa..75779f5a68 100644
--- a/api/src/backend/config/django/testing.py
+++ b/api/src/backend/config/django/testing.py
@@ -18,6 +18,10 @@ DATABASES = {
DATABASE_ROUTERS = []
TESTING = True
+# Override page size for testing to a value only slightly above the current fixture count.
+# We explicitly set PAGE_SIZE to 15 (round number just above fixture) to avoid masking pagination bugs, while not setting it excessively high.
+# If you add more providers to the fixture, please review that the total value is below the current one and update this value if needed.
+REST_FRAMEWORK["PAGE_SIZE"] = 15 # noqa: F405
SECRETS_ENCRYPTION_KEY = "ZMiYVo7m4Fbe2eXXPyrwxdJss2WSalXSv3xHBcJkPl0="
# DRF Simple API Key settings
diff --git a/api/src/backend/conftest.py b/api/src/backend/conftest.py
index e50f92e1ab..189d5a31d5 100644
--- a/api/src/backend/conftest.py
+++ b/api/src/backend/conftest.py
@@ -537,6 +537,12 @@ def providers_fixture(tenants_fixture):
alias="cloudflare_testing",
tenant_id=tenant.id,
)
+ provider11 = Provider.objects.create(
+ provider="openstack",
+ uid="a1b2c3d4-e5f6-7890-abcd-ef1234567890",
+ alias="openstack_testing",
+ tenant_id=tenant.id,
+ )
return (
provider1,
@@ -549,6 +555,7 @@ def providers_fixture(tenants_fixture):
provider8,
provider9,
provider10,
+ provider11,
)
@@ -1618,7 +1625,6 @@ def create_attack_paths_scan():
scan=None,
state=StateChoices.COMPLETED,
progress=0,
- graph_database="tenant-db",
**extra_fields,
):
scan_instance = scan or Scan.objects.create(
@@ -1635,7 +1641,6 @@ def create_attack_paths_scan():
"scan": scan_instance,
"state": state,
"progress": progress,
- "graph_database": graph_database,
}
payload.update(extra_fields)
@@ -1663,6 +1668,7 @@ def attack_paths_query_definition_factory():
definition_payload = {
"id": "aws-test",
"name": "Attack Paths Test Query",
+ "short_description": "Synthetic short description for tests.",
"description": "Synthetic Attack Paths definition for tests.",
"provider": "aws",
"cypher": "RETURN 1",
diff --git a/api/src/backend/tasks/jobs/attack_paths/config.py b/api/src/backend/tasks/jobs/attack_paths/config.py
index d39e6fa81f..af8094e172 100644
--- a/api/src/backend/tasks/jobs/attack_paths/config.py
+++ b/api/src/backend/tasks/jobs/attack_paths/config.py
@@ -12,8 +12,10 @@ BATCH_SIZE = env.int("ATTACK_PATHS_BATCH_SIZE", 1000)
# Neo4j internal labels (Prowler-specific, not provider-specific)
# - `ProwlerFinding`: Label for finding nodes created by Prowler and linked to cloud resources.
# - `ProviderResource`: Added to ALL synced nodes for provider isolation and drop/query ops.
+# - `Internet`: Singleton node representing external internet access for exposed-resource queries.
PROWLER_FINDING_LABEL = "ProwlerFinding"
PROVIDER_RESOURCE_LABEL = "ProviderResource"
+INTERNET_NODE_LABEL = "Internet"
@dataclass(frozen=True)
diff --git a/api/src/backend/tasks/jobs/attack_paths/db_utils.py b/api/src/backend/tasks/jobs/attack_paths/db_utils.py
index c9bbf5afdf..9fb52b0ead 100644
--- a/api/src/backend/tasks/jobs/attack_paths/db_utils.py
+++ b/api/src/backend/tasks/jobs/attack_paths/db_utils.py
@@ -2,7 +2,9 @@ from datetime import datetime, timezone
from typing import Any
from cartography.config import Config as CartographyConfig
+from celery.utils.log import get_task_logger
+from api.attack_paths import database as graph_database
from api.db_utils import rls_transaction
from api.models import (
AttackPathsScan as ProwlerAPIAttackPathsScan,
@@ -11,6 +13,8 @@ from api.models import (
)
from tasks.jobs.attack_paths.config import is_provider_available
+logger = get_task_logger(__name__)
+
def can_provider_run_attack_paths_scan(tenant_id: str, provider_id: int) -> bool:
with rls_transaction(tenant_id):
@@ -28,12 +32,21 @@ def create_attack_paths_scan(
return None
with rls_transaction(tenant_id):
+ # Inherit graph_data_ready from the previous scan for this provider,
+ # so queries remain available while the new scan runs.
+ previous_data_ready = ProwlerAPIAttackPathsScan.objects.filter(
+ tenant_id=tenant_id,
+ provider_id=provider_id,
+ graph_data_ready=True,
+ ).exists()
+
attack_paths_scan = ProwlerAPIAttackPathsScan.objects.create(
tenant_id=tenant_id,
provider_id=provider_id,
scan_id=scan_id,
state=StateChoices.SCHEDULED,
started_at=datetime.now(tz=timezone.utc),
+ graph_data_ready=previous_data_ready,
)
attack_paths_scan.save()
@@ -66,7 +79,6 @@ def starting_attack_paths_scan(
attack_paths_scan.state = StateChoices.EXECUTING
attack_paths_scan.started_at = datetime.now(tz=timezone.utc)
attack_paths_scan.update_tag = cartography_config.update_tag
- attack_paths_scan.graph_database = cartography_config.neo4j_database
attack_paths_scan.save(
update_fields=[
@@ -74,7 +86,6 @@ def starting_attack_paths_scan(
"state",
"started_at",
"update_tag",
- "graph_database",
]
)
@@ -86,7 +97,11 @@ def finish_attack_paths_scan(
) -> None:
with rls_transaction(attack_paths_scan.tenant_id):
now = datetime.now(tz=timezone.utc)
- duration = int((now - attack_paths_scan.started_at).total_seconds())
+ duration = (
+ int((now - attack_paths_scan.started_at).total_seconds())
+ if attack_paths_scan.started_at
+ else 0
+ )
attack_paths_scan.state = state
attack_paths_scan.progress = 100
@@ -114,33 +129,59 @@ def update_attack_paths_scan_progress(
attack_paths_scan.save(update_fields=["progress"])
-def get_old_attack_paths_scans(
- tenant_id: str,
- provider_id: str,
- attack_paths_scan_id: str,
-) -> list[ProwlerAPIAttackPathsScan]:
- """
- An `old_attack_paths_scan` is any `completed` Attack Paths scan for the same provider,
- with its graph database not deleted, excluding the current Attack Paths scan.
- """
-
- with rls_transaction(tenant_id):
- completed_scans_qs = (
- ProwlerAPIAttackPathsScan.objects.filter(
- provider_id=provider_id,
- state=StateChoices.COMPLETED,
- is_graph_database_deleted=False,
- )
- .exclude(id=attack_paths_scan_id)
- .all()
- )
-
- return list(completed_scans_qs)
-
-
-def update_old_attack_paths_scan(
- old_attack_paths_scan: ProwlerAPIAttackPathsScan,
+def set_graph_data_ready(
+ attack_paths_scan: ProwlerAPIAttackPathsScan,
+ ready: bool,
) -> None:
- with rls_transaction(old_attack_paths_scan.tenant_id):
- old_attack_paths_scan.is_graph_database_deleted = True
- old_attack_paths_scan.save(update_fields=["is_graph_database_deleted"])
+ with rls_transaction(attack_paths_scan.tenant_id):
+ attack_paths_scan.graph_data_ready = ready
+ attack_paths_scan.save(update_fields=["graph_data_ready"])
+
+
+def set_provider_graph_data_ready(
+ attack_paths_scan: ProwlerAPIAttackPathsScan,
+ ready: bool,
+) -> None:
+ """
+ Set `graph_data_ready` for ALL scans of the same provider.
+
+ Used before drop/sync so that older scan IDs cannot bypass the query gate while the graph is being replaced.
+ """
+ with rls_transaction(attack_paths_scan.tenant_id):
+ ProwlerAPIAttackPathsScan.objects.filter(
+ tenant_id=attack_paths_scan.tenant_id,
+ provider_id=attack_paths_scan.provider_id,
+ ).update(graph_data_ready=ready)
+ attack_paths_scan.refresh_from_db(fields=["graph_data_ready"])
+
+
+def fail_attack_paths_scan(
+ tenant_id: str,
+ scan_id: str,
+ error: str,
+) -> None:
+ """
+ Mark the `AttackPathsScan` row as `FAILED` unless it's already `COMPLETED` or `FAILED`.
+ Used as a safety net when the Celery task fails outside the job's own error handling.
+ """
+ attack_paths_scan = retrieve_attack_paths_scan(tenant_id, scan_id)
+ if attack_paths_scan and attack_paths_scan.state not in (
+ StateChoices.COMPLETED,
+ StateChoices.FAILED,
+ ):
+ tmp_db_name = graph_database.get_database_name(
+ attack_paths_scan.id, temporary=True
+ )
+ try:
+ graph_database.drop_database(tmp_db_name)
+
+ except Exception:
+ logger.exception(
+ f"Failed to drop temp database {tmp_db_name} during failure handling"
+ )
+
+ finish_attack_paths_scan(
+ attack_paths_scan,
+ StateChoices.FAILED,
+ {"global_error": error},
+ )
diff --git a/api/src/backend/tasks/jobs/attack_paths/indexes.py b/api/src/backend/tasks/jobs/attack_paths/indexes.py
index 708e9c7f84..9ccd8cab04 100644
--- a/api/src/backend/tasks/jobs/attack_paths/indexes.py
+++ b/api/src/backend/tasks/jobs/attack_paths/indexes.py
@@ -6,6 +6,7 @@ from cartography.client.core.tx import run_write_query
from celery.utils.log import get_task_logger
from tasks.jobs.attack_paths.config import (
+ INTERNET_NODE_LABEL,
PROWLER_FINDING_LABEL,
PROVIDER_RESOURCE_LABEL,
)
@@ -30,6 +31,8 @@ FINDINGS_INDEX_STATEMENTS = [
f"CREATE INDEX prowler_finding_provider_uid IF NOT EXISTS FOR (n:{PROWLER_FINDING_LABEL}) ON (n.provider_uid);",
f"CREATE INDEX prowler_finding_lastupdated IF NOT EXISTS FOR (n:{PROWLER_FINDING_LABEL}) ON (n.lastupdated);",
f"CREATE INDEX prowler_finding_status IF NOT EXISTS FOR (n:{PROWLER_FINDING_LABEL}) ON (n.status);",
+ # Internet node index for MERGE lookups
+ f"CREATE INDEX internet_id IF NOT EXISTS FOR (n:{INTERNET_NODE_LABEL}) ON (n.id);",
]
# Indexes for provider resource sync operations
diff --git a/api/src/backend/tasks/jobs/attack_paths/internet.py b/api/src/backend/tasks/jobs/attack_paths/internet.py
new file mode 100644
index 0000000000..83517bc903
--- /dev/null
+++ b/api/src/backend/tasks/jobs/attack_paths/internet.py
@@ -0,0 +1,67 @@
+"""
+Internet node enrichment for Attack Paths graph.
+
+Creates a real Internet node and CAN_ACCESS relationships to
+internet-exposed resources (EC2Instance, LoadBalancer, LoadBalancerV2)
+in the temporary scan database before sync.
+"""
+
+import neo4j
+
+from cartography.config import Config as CartographyConfig
+from celery.utils.log import get_task_logger
+
+from api.models import Provider
+from prowler.config import config as ProwlerConfig
+from tasks.jobs.attack_paths.config import get_root_node_label
+from tasks.jobs.attack_paths.queries import (
+ CREATE_CAN_ACCESS_RELATIONSHIPS_TEMPLATE,
+ CREATE_INTERNET_NODE,
+ render_cypher_template,
+)
+
+logger = get_task_logger(__name__)
+
+
+def analysis(
+ neo4j_session: neo4j.Session,
+ prowler_api_provider: Provider,
+ config: CartographyConfig,
+) -> int:
+ """
+ Create Internet node and CAN_ACCESS relationships to exposed resources.
+
+ Args:
+ neo4j_session: Active Neo4j session (temp database).
+ prowler_api_provider: The Prowler API provider instance.
+ config: Cartography configuration with update_tag.
+
+ Returns:
+ Number of CAN_ACCESS relationships created.
+ """
+ provider_uid = str(prowler_api_provider.uid)
+
+ parameters = {
+ "provider_uid": provider_uid,
+ "last_updated": config.update_tag,
+ "prowler_version": ProwlerConfig.prowler_version,
+ }
+
+ logger.info(f"Creating Internet node for provider {provider_uid}")
+ neo4j_session.run(CREATE_INTERNET_NODE, parameters)
+
+ query = render_cypher_template(
+ CREATE_CAN_ACCESS_RELATIONSHIPS_TEMPLATE,
+ {"__ROOT_LABEL__": get_root_node_label(prowler_api_provider.provider)},
+ )
+
+ logger.info(
+ f"Creating CAN_ACCESS relationships from Internet to exposed resources for {provider_uid}"
+ )
+ result = neo4j_session.run(query, parameters)
+ relationships_merged = result.single().get("relationships_merged", 0)
+
+ logger.info(
+ f"Created {relationships_merged} CAN_ACCESS relationships for provider {provider_uid}"
+ )
+ return relationships_merged
diff --git a/api/src/backend/tasks/jobs/attack_paths/queries.py b/api/src/backend/tasks/jobs/attack_paths/queries.py
index bf935cc9ca..75ef9ec5b3 100644
--- a/api/src/backend/tasks/jobs/attack_paths/queries.py
+++ b/api/src/backend/tasks/jobs/attack_paths/queries.py
@@ -1,5 +1,6 @@
# Cypher query templates for Attack Paths operations
from tasks.jobs.attack_paths.config import (
+ INTERNET_NODE_LABEL,
PROWLER_FINDING_LABEL,
PROVIDER_RESOURCE_LABEL,
)
@@ -91,6 +92,37 @@ CLEANUP_FINDINGS_TEMPLATE = f"""
RETURN COUNT(finding) AS deleted_findings_count
"""
+# Internet queries (used by internet.py)
+# ---------------------------------------
+
+CREATE_INTERNET_NODE = f"""
+ MERGE (internet:{INTERNET_NODE_LABEL} {{id: 'Internet'}})
+ ON CREATE SET
+ internet.name = 'Internet',
+ internet.firstseen = timestamp(),
+ internet.lastupdated = $last_updated,
+ internet._module_name = 'cartography:prowler',
+ internet._module_version = $prowler_version
+ ON MATCH SET
+ internet.lastupdated = $last_updated
+"""
+
+CREATE_CAN_ACCESS_RELATIONSHIPS_TEMPLATE = f"""
+ MATCH (account:__ROOT_LABEL__ {{id: $provider_uid}})-->(resource)
+ WHERE resource.exposed_internet = true
+ WITH resource
+ MATCH (internet:{INTERNET_NODE_LABEL} {{id: 'Internet'}})
+ MERGE (internet)-[r:CAN_ACCESS]->(resource)
+ ON CREATE SET
+ r.firstseen = timestamp(),
+ r.lastupdated = $last_updated,
+ r._module_name = 'cartography:prowler',
+ r._module_version = $prowler_version
+ ON MATCH SET
+ r.lastupdated = $last_updated
+ RETURN COUNT(r) AS relationships_merged
+"""
+
# Sync queries (used by sync.py)
# -------------------------------
diff --git a/api/src/backend/tasks/jobs/attack_paths/scan.py b/api/src/backend/tasks/jobs/attack_paths/scan.py
index 1ffcbf55e7..da70b77383 100644
--- a/api/src/backend/tasks/jobs/attack_paths/scan.py
+++ b/api/src/backend/tasks/jobs/attack_paths/scan.py
@@ -16,7 +16,7 @@ from api.models import (
StateChoices,
)
from api.utils import initialize_prowler_provider
-from tasks.jobs.attack_paths import db_utils, findings, sync, utils
+from tasks.jobs.attack_paths import db_utils, findings, internet, sync, utils
from tasks.jobs.attack_paths.config import get_cartography_ingestion_function
# Without this Celery goes crazy with Cartography logging
@@ -135,7 +135,15 @@ def run(tenant_id: str, scan_id: str, task_id: str) -> dict[str, Any]:
cartography_analysis.run(tmp_neo4j_session, tmp_cartography_config)
db_utils.update_attack_paths_scan_progress(attack_paths_scan, 96)
- # Adding Prowler nodes and relationships
+ # Creating Internet node and CAN_ACCESS relationships
+ logger.info(
+ f"Creating Internet graph for AWS account {prowler_api_provider.uid}"
+ )
+ internet.analysis(
+ tmp_neo4j_session, prowler_api_provider, tmp_cartography_config
+ )
+
+ # Adding Prowler Finding nodes and relationships
logger.info(
f"Syncing Prowler analysis for AWS account {prowler_api_provider.uid}"
)
@@ -161,6 +169,7 @@ def run(tenant_id: str, scan_id: str, task_id: str) -> dict[str, Any]:
sync.create_sync_indexes(tenant_neo4j_session)
logger.info(f"Deleting existing provider graph in {tenant_database_name}")
+ db_utils.set_provider_graph_data_ready(attack_paths_scan, False)
graph_database.drop_subgraph(
database=tenant_database_name,
provider_id=str(prowler_api_provider.id),
@@ -175,6 +184,7 @@ def run(tenant_id: str, scan_id: str, task_id: str) -> dict[str, Any]:
target_database=tenant_database_name,
provider_id=str(prowler_api_provider.id),
)
+ db_utils.set_graph_data_ready(attack_paths_scan, True)
db_utils.update_attack_paths_scan_progress(attack_paths_scan, 99)
logger.info(f"Clearing Neo4j cache for database {tenant_database_name}")
@@ -185,30 +195,6 @@ def run(tenant_id: str, scan_id: str, task_id: str) -> dict[str, Any]:
f"{prowler_api_provider.provider.upper()} provider {prowler_api_provider.id}"
)
- # TODO
- # This piece of code delete old Neo4j databases for this tenant's provider
- # When we clean all of these databases we need to:
- # - Delete this block
- # - Delete function from `db_utils` the functions get_old_attack_paths_scans` & `update_old_attack_paths_scan`
- # - Remove `graph_database` & `is_graph_database_deleted` from the AttackPathsScan model:
- # - Check indexes
- # - Create migration
- # - The use of `attack_paths_scan.graph_database` on `views` and `views_helpers`
- # - Tests
- old_attack_paths_scans = db_utils.get_old_attack_paths_scans(
- prowler_api_provider.tenant_id,
- prowler_api_provider.id,
- attack_paths_scan.id,
- )
- for old_attack_paths_scan in old_attack_paths_scans:
- old_graph_database = old_attack_paths_scan.graph_database
- if old_graph_database and old_graph_database != tenant_database_name:
- logger.info(
- f"Dropping old Neo4j database {old_graph_database} for provider {prowler_api_provider.id}"
- )
- graph_database.drop_database(old_graph_database)
- db_utils.update_old_attack_paths_scan(old_attack_paths_scan)
-
logger.info(f"Dropping temporary Neo4j database {tmp_database_name}")
graph_database.drop_database(tmp_database_name)
@@ -220,10 +206,17 @@ def run(tenant_id: str, scan_id: str, task_id: str) -> dict[str, Any]:
except Exception as e:
exception_message = utils.stringify_exception(e, "Cartography failed")
logger.error(exception_message)
- ingestion_exceptions["global_cartography_error"] = exception_message
+ ingestion_exceptions["global_error"] = exception_message
# Handling databases changes
- graph_database.drop_database(tmp_cartography_config.neo4j_database)
+ try:
+ graph_database.drop_database(tmp_cartography_config.neo4j_database)
+
+ except Exception:
+ logger.exception(
+ f"Failed to drop temporary Neo4j database {tmp_cartography_config.neo4j_database} during cleanup"
+ )
+
db_utils.finish_attack_paths_scan(
attack_paths_scan, StateChoices.FAILED, ingestion_exceptions
)
diff --git a/api/src/backend/tasks/jobs/deletion.py b/api/src/backend/tasks/jobs/deletion.py
index ba59eaeb5f..21c9031bf5 100644
--- a/api/src/backend/tasks/jobs/deletion.py
+++ b/api/src/backend/tasks/jobs/deletion.py
@@ -27,23 +27,24 @@ def delete_provider(tenant_id: str, pk: str):
Returns:
dict: A dictionary with the count of deleted objects per model,
- including related models.
-
- Raises:
- Provider.DoesNotExist: If no instance with the provided primary key exists.
+ including related models. Returns an empty dict if the provider
+ was already deleted.
"""
- # Delete the Attack Paths' graph data related to the provider
- tenant_database_name = graph_database.get_database_name(tenant_id)
- try:
- graph_database.drop_subgraph(tenant_database_name, str(pk))
- except graph_database.GraphDatabaseQueryException as gdb_error:
- logger.error(f"Error deleting Provider graph data: {gdb_error}")
- raise
-
- # Get all provider related data and delete them in batches
+ # Get all provider related data to delete them in batches
with rls_transaction(tenant_id):
- instance = Provider.all_objects.get(pk=pk)
+ try:
+ instance = Provider.all_objects.get(pk=pk)
+ except Provider.DoesNotExist:
+ logger.info(f"Provider `{pk}` already deleted, skipping")
+ return {}
+
+ attack_paths_scan_ids = list(
+ AttackPathsScan.all_objects.filter(provider=instance).values_list(
+ "id", flat=True
+ )
+ )
+
deletion_steps = [
("Scan Summaries", ScanSummary.all_objects.filter(scan__provider=instance)),
("Findings", Finding.all_objects.filter(scan__provider=instance)),
@@ -52,6 +53,25 @@ def delete_provider(tenant_id: str, pk: str):
("AttackPathsScans", AttackPathsScan.all_objects.filter(provider=instance)),
]
+ # Drop orphaned temporary Neo4j databases
+ for aps_id in attack_paths_scan_ids:
+ tmp_db_name = graph_database.get_database_name(aps_id, temporary=True)
+ try:
+ graph_database.drop_database(tmp_db_name)
+
+ except graph_database.GraphDatabaseQueryException:
+ logger.warning(f"Failed to drop temp database {tmp_db_name}, continuing")
+
+ # Delete the Attack Paths' graph data related to the provider from the tenant database
+ tenant_database_name = graph_database.get_database_name(tenant_id)
+ try:
+ graph_database.drop_subgraph(tenant_database_name, str(pk))
+
+ except graph_database.GraphDatabaseQueryException as gdb_error:
+ logger.error(f"Error deleting Provider graph data: {gdb_error}")
+ raise
+
+ # Delete related data in batches
deletion_summary = {}
for step_name, queryset in deletion_steps:
try:
@@ -61,6 +81,7 @@ def delete_provider(tenant_id: str, pk: str):
logger.error(f"Error deleting {step_name}: {db_error}")
raise
+ # Delete the provider instance itself
try:
with rls_transaction(tenant_id):
_, provider_summary = instance.delete()
@@ -85,7 +106,9 @@ def delete_tenant(pk: str):
"""
deletion_summary = {}
- for provider in Provider.objects.using(MainRouter.admin_db).filter(tenant_id=pk):
+ for provider in Provider.all_objects.using(MainRouter.admin_db).filter(
+ tenant_id=pk
+ ):
summary = delete_provider(pk, provider.id)
deletion_summary.update(summary)
diff --git a/api/src/backend/tasks/jobs/export.py b/api/src/backend/tasks/jobs/export.py
index 883d7d0dbe..c2a947d249 100644
--- a/api/src/backend/tasks/jobs/export.py
+++ b/api/src/backend/tasks/jobs/export.py
@@ -35,6 +35,11 @@ from prowler.lib.outputs.compliance.cis.cis_github import GithubCIS
from prowler.lib.outputs.compliance.cis.cis_kubernetes import KubernetesCIS
from prowler.lib.outputs.compliance.cis.cis_m365 import M365CIS
from prowler.lib.outputs.compliance.cis.cis_oraclecloud import OracleCloudCIS
+from prowler.lib.outputs.compliance.csa.csa_alibabacloud import AlibabaCloudCSA
+from prowler.lib.outputs.compliance.csa.csa_aws import AWSCSA
+from prowler.lib.outputs.compliance.csa.csa_azure import AzureCSA
+from prowler.lib.outputs.compliance.csa.csa_gcp import GCPCSA
+from prowler.lib.outputs.compliance.csa.csa_oraclecloud import OracleCloudCSA
from prowler.lib.outputs.compliance.ens.ens_aws import AWSENS
from prowler.lib.outputs.compliance.ens.ens_azure import AzureENS
from prowler.lib.outputs.compliance.ens.ens_gcp import GCPENS
@@ -90,6 +95,7 @@ COMPLIANCE_CLASS_MAP = {
(lambda name: name == "prowler_threatscore_aws", ProwlerThreatScoreAWS),
(lambda name: name == "ccc_aws", CCC_AWS),
(lambda name: name.startswith("c5_"), AWSC5),
+ (lambda name: name.startswith("csa_"), AWSCSA),
],
"azure": [
(lambda name: name.startswith("cis_"), AzureCIS),
@@ -99,6 +105,7 @@ COMPLIANCE_CLASS_MAP = {
(lambda name: name == "ccc_azure", CCC_Azure),
(lambda name: name == "prowler_threatscore_azure", ProwlerThreatScoreAzure),
(lambda name: name == "c5_azure", AzureC5),
+ (lambda name: name.startswith("csa_"), AzureCSA),
],
"gcp": [
(lambda name: name.startswith("cis_"), GCPCIS),
@@ -108,6 +115,7 @@ COMPLIANCE_CLASS_MAP = {
(lambda name: name == "prowler_threatscore_gcp", ProwlerThreatScoreGCP),
(lambda name: name == "ccc_gcp", CCC_GCP),
(lambda name: name == "c5_gcp", GCPC5),
+ (lambda name: name.startswith("csa_"), GCPCSA),
],
"kubernetes": [
(lambda name: name.startswith("cis_"), KubernetesCIS),
@@ -131,9 +139,11 @@ COMPLIANCE_CLASS_MAP = {
],
"oraclecloud": [
(lambda name: name.startswith("cis_"), OracleCloudCIS),
+ (lambda name: name.startswith("csa_"), OracleCloudCSA),
],
"alibabacloud": [
(lambda name: name.startswith("cis_"), AlibabaCloudCIS),
+ (lambda name: name.startswith("csa_"), AlibabaCloudCSA),
(
lambda name: name == "prowler_threatscore_alibabacloud",
ProwlerThreatScoreAlibaba,
diff --git a/api/src/backend/tasks/jobs/report.py b/api/src/backend/tasks/jobs/report.py
index de022e9afd..a41a8d6292 100644
--- a/api/src/backend/tasks/jobs/report.py
+++ b/api/src/backend/tasks/jobs/report.py
@@ -6,6 +6,7 @@ from config.django.base import DJANGO_TMP_OUTPUT_DIRECTORY
from tasks.jobs.export import _generate_compliance_output_directory, _upload_to_s3
from tasks.jobs.reports import (
FRAMEWORK_REGISTRY,
+ CSAReportGenerator,
ENSReportGenerator,
NIS2ReportGenerator,
ThreatScoreReportGenerator,
@@ -147,6 +148,49 @@ def generate_nis2_report(
)
+def generate_csa_report(
+ tenant_id: str,
+ scan_id: str,
+ compliance_id: str,
+ output_path: str,
+ provider_id: str,
+ only_failed: bool = True,
+ include_manual: bool = False,
+ provider_obj: Provider | None = None,
+ requirement_statistics: dict[str, dict[str, int]] | None = None,
+ findings_cache: dict[str, list[FindingOutput]] | None = None,
+) -> None:
+ """
+ Generate a PDF compliance report for CSA Cloud Controls Matrix (CCM) v4.0.
+
+ Args:
+ tenant_id: The tenant ID for Row-Level Security context.
+ scan_id: ID of the scan executed by Prowler.
+ compliance_id: ID of the compliance framework (e.g., "csa_ccm_4.0_aws").
+ output_path: Output PDF file path.
+ provider_id: Provider ID for the scan.
+ only_failed: If True, only include failed requirements in detailed section.
+ include_manual: If True, include manual requirements in detailed section.
+ provider_obj: Pre-fetched Provider object to avoid duplicate queries.
+ requirement_statistics: Pre-aggregated requirement statistics.
+ findings_cache: Cache of already loaded findings to avoid duplicate queries.
+ """
+ generator = CSAReportGenerator(FRAMEWORK_REGISTRY["csa_ccm"])
+
+ generator.generate(
+ tenant_id=tenant_id,
+ scan_id=scan_id,
+ compliance_id=compliance_id,
+ output_path=output_path,
+ provider_id=provider_id,
+ provider_obj=provider_obj,
+ requirement_statistics=requirement_statistics,
+ findings_cache=findings_cache,
+ only_failed=only_failed,
+ include_manual=include_manual,
+ )
+
+
def generate_compliance_reports(
tenant_id: str,
scan_id: str,
@@ -154,11 +198,14 @@ def generate_compliance_reports(
generate_threatscore: bool = True,
generate_ens: bool = True,
generate_nis2: bool = True,
+ generate_csa: bool = True,
only_failed_threatscore: bool = True,
min_risk_level_threatscore: int = 4,
include_manual_ens: bool = True,
include_manual_nis2: bool = False,
only_failed_nis2: bool = True,
+ only_failed_csa: bool = True,
+ include_manual_csa: bool = False,
) -> dict[str, dict[str, bool | str]]:
"""
Generate multiple compliance reports with shared database queries.
@@ -175,23 +222,27 @@ def generate_compliance_reports(
generate_threatscore: Whether to generate ThreatScore report.
generate_ens: Whether to generate ENS report.
generate_nis2: Whether to generate NIS2 report.
+ generate_csa: Whether to generate CSA CCM report.
only_failed_threatscore: For ThreatScore, only include failed requirements.
min_risk_level_threatscore: Minimum risk level for ThreatScore critical requirements.
include_manual_ens: For ENS, include manual requirements.
include_manual_nis2: For NIS2, include manual requirements.
only_failed_nis2: For NIS2, only include failed requirements.
+ only_failed_csa: For CSA CCM, only include failed requirements.
+ include_manual_csa: For CSA CCM, include manual requirements.
Returns:
Dictionary with results for each report type.
"""
logger.info(
"Generating compliance reports for scan %s with provider %s"
- " (ThreatScore: %s, ENS: %s, NIS2: %s)",
+ " (ThreatScore: %s, ENS: %s, NIS2: %s, CSA: %s)",
scan_id,
provider_id,
generate_threatscore,
generate_ens,
generate_nis2,
+ generate_csa,
)
results = {}
@@ -206,6 +257,8 @@ def generate_compliance_reports(
results["ens"] = {"upload": False, "path": ""}
if generate_nis2:
results["nis2"] = {"upload": False, "path": ""}
+ if generate_csa:
+ results["csa"] = {"upload": False, "path": ""}
return results
provider_obj = Provider.objects.get(id=provider_id)
@@ -235,7 +288,23 @@ def generate_compliance_reports(
results["nis2"] = {"upload": False, "path": ""}
generate_nis2 = False
- if not generate_threatscore and not generate_ens and not generate_nis2:
+ if generate_csa and provider_type not in [
+ "aws",
+ "azure",
+ "gcp",
+ "oraclecloud",
+ "alibabacloud",
+ ]:
+ logger.info("Provider %s not supported for CSA CCM report", provider_type)
+ results["csa"] = {"upload": False, "path": ""}
+ generate_csa = False
+
+ if (
+ not generate_threatscore
+ and not generate_ens
+ and not generate_nis2
+ and not generate_csa
+ ):
return results
# Aggregate requirement statistics once
@@ -274,6 +343,13 @@ def generate_compliance_reports(
scan_id,
compliance_framework="nis2",
)
+ csa_path = _generate_compliance_output_directory(
+ DJANGO_TMP_OUTPUT_DIRECTORY,
+ provider_uid,
+ tenant_id,
+ scan_id,
+ compliance_framework="csa",
+ )
out_dir = str(Path(threatscore_path).parent.parent)
except Exception as e:
logger.error("Error generating output directory: %s", e)
@@ -284,6 +360,8 @@ def generate_compliance_reports(
results["ens"] = error_dict.copy()
if generate_nis2:
results["nis2"] = error_dict.copy()
+ if generate_csa:
+ results["csa"] = error_dict.copy()
return results
# Generate ThreatScore report
@@ -456,6 +534,41 @@ def generate_compliance_reports(
logger.error("Error generating NIS2 report: %s", e)
results["nis2"] = {"upload": False, "path": "", "error": str(e)}
+ # Generate CSA CCM report
+ if generate_csa:
+ compliance_id_csa = f"csa_ccm_4.0_{provider_type}"
+ pdf_path_csa = f"{csa_path}_csa_report.pdf"
+ logger.info("Generating CSA CCM report with compliance %s", compliance_id_csa)
+
+ try:
+ generate_csa_report(
+ tenant_id=tenant_id,
+ scan_id=scan_id,
+ compliance_id=compliance_id_csa,
+ output_path=pdf_path_csa,
+ provider_id=provider_id,
+ only_failed=only_failed_csa,
+ include_manual=include_manual_csa,
+ provider_obj=provider_obj,
+ requirement_statistics=requirement_statistics,
+ findings_cache=findings_cache,
+ )
+
+ upload_uri_csa = _upload_to_s3(
+ tenant_id, scan_id, pdf_path_csa, f"csa/{Path(pdf_path_csa).name}"
+ )
+
+ if upload_uri_csa:
+ results["csa"] = {"upload": True, "path": upload_uri_csa}
+ logger.info("CSA CCM report uploaded to %s", upload_uri_csa)
+ else:
+ results["csa"] = {"upload": False, "path": out_dir}
+ logger.warning("CSA CCM report saved locally at %s", out_dir)
+
+ except Exception as e:
+ logger.error("Error generating CSA CCM report: %s", e)
+ results["csa"] = {"upload": False, "path": "", "error": str(e)}
+
# Clean up temporary files if all reports were uploaded successfully
all_uploaded = all(
result.get("upload", False)
@@ -481,6 +594,7 @@ def generate_compliance_reports_job(
generate_threatscore: bool = True,
generate_ens: bool = True,
generate_nis2: bool = True,
+ generate_csa: bool = True,
) -> dict[str, dict[str, bool | str]]:
"""
Celery task wrapper for generate_compliance_reports.
@@ -492,6 +606,7 @@ def generate_compliance_reports_job(
generate_threatscore: Whether to generate ThreatScore report.
generate_ens: Whether to generate ENS report.
generate_nis2: Whether to generate NIS2 report.
+ generate_csa: Whether to generate CSA CCM report.
Returns:
Dictionary with results for each report type.
@@ -503,4 +618,5 @@ def generate_compliance_reports_job(
generate_threatscore=generate_threatscore,
generate_ens=generate_ens,
generate_nis2=generate_nis2,
+ generate_csa=generate_csa,
)
diff --git a/api/src/backend/tasks/jobs/reports/__init__.py b/api/src/backend/tasks/jobs/reports/__init__.py
index 60602b93ab..1fc475a467 100644
--- a/api/src/backend/tasks/jobs/reports/__init__.py
+++ b/api/src/backend/tasks/jobs/reports/__init__.py
@@ -71,6 +71,8 @@ from .config import (
COLOR_PROWLER_DARK_GREEN,
COLOR_SAFE,
COLOR_WHITE,
+ CSA_CCM_SECTION_SHORT_NAMES,
+ CSA_CCM_SECTIONS,
DIMENSION_KEYS,
DIMENSION_MAPPING,
DIMENSION_NAMES,
@@ -90,6 +92,7 @@ from .config import (
)
# Framework-specific generators
+from .csa import CSAReportGenerator
from .ens import ENSReportGenerator
from .nis2 import NIS2ReportGenerator
from .threatscore import ThreatScoreReportGenerator
@@ -105,6 +108,7 @@ __all__ = [
"ThreatScoreReportGenerator",
"ENSReportGenerator",
"NIS2ReportGenerator",
+ "CSAReportGenerator",
# Configuration
"FrameworkConfig",
"FRAMEWORK_REGISTRY",
@@ -147,6 +151,8 @@ __all__ = [
"THREATSCORE_SECTIONS",
"NIS2_SECTIONS",
"NIS2_SECTION_TITLES",
+ "CSA_CCM_SECTIONS",
+ "CSA_CCM_SECTION_SHORT_NAMES",
# Layout constants
"COL_WIDTH_SMALL",
"COL_WIDTH_MEDIUM",
diff --git a/api/src/backend/tasks/jobs/reports/base.py b/api/src/backend/tasks/jobs/reports/base.py
index 42776681fb..f348c6d0d2 100644
--- a/api/src/backend/tasks/jobs/reports/base.py
+++ b/api/src/backend/tasks/jobs/reports/base.py
@@ -662,6 +662,9 @@ class BaseComplianceReportGenerator(ABC):
elements.append(create_status_badge(req.status))
elements.append(Spacer(1, 0.1 * inch))
+ # Hook for subclasses to add extra detail (e.g., CSA attributes)
+ elements.extend(self._render_requirement_detail_extras(req, data))
+
# Findings for this requirement
for check_id in req.checks:
elements.append(Paragraph(f"Check: {check_id}", self.styles["h2"]))
@@ -701,6 +704,24 @@ class BaseComplianceReportGenerator(ABC):
return page_text, "Powered by Prowler"
+ def _render_requirement_detail_extras(
+ self, req: RequirementData, data: ComplianceData
+ ) -> list:
+ """Hook for subclasses to render extra content in detailed findings.
+
+ Called after the status badge for each requirement in the detailed
+ findings section. Override in subclasses to add framework-specific
+ metadata (e.g., CSA CCM attributes).
+
+ Args:
+ req: The requirement being rendered.
+ data: Aggregated compliance data.
+
+ Returns:
+ List of ReportLab elements (empty by default).
+ """
+ return []
+
# =========================================================================
# Private Helper Methods
# =========================================================================
diff --git a/api/src/backend/tasks/jobs/reports/config.py b/api/src/backend/tasks/jobs/reports/config.py
index 0785505820..fe0326980d 100644
--- a/api/src/backend/tasks/jobs/reports/config.py
+++ b/api/src/backend/tasks/jobs/reports/config.py
@@ -143,6 +143,36 @@ NIS2_SECTION_TITLES = {
"12": "12. Asset Management",
}
+# CSA CCM sections (Cloud Controls Matrix v4.0 domains)
+CSA_CCM_SECTIONS = [
+ "Application & Interface Security",
+ "Audit & Assurance",
+ "Business Continuity Management and Operational Resilience",
+ "Change Control and Configuration Management",
+ "Cryptography, Encryption & Key Management",
+ "Data Security and Privacy Lifecycle Management",
+ "Datacenter Security",
+ "Governance, Risk and Compliance",
+ "Identity & Access Management",
+ "Infrastructure & Virtualization Security",
+ "Interoperability & Portability",
+ "Logging and Monitoring",
+ "Security Incident Management, E-Discovery, & Cloud Forensics",
+ "Threat & Vulnerability Management",
+ "Universal Endpoint Management",
+]
+
+# Short names for CSA CCM sections (used in chart labels)
+CSA_CCM_SECTION_SHORT_NAMES = {
+ "Application & Interface Security": "App & Interface Security",
+ "Business Continuity Management and Operational Resilience": "Business Continuity",
+ "Change Control and Configuration Management": "Change Control & Config",
+ "Cryptography, Encryption & Key Management": "Cryptography & Encryption",
+ "Data Security and Privacy Lifecycle Management": "Data Security & Privacy",
+ "Security Incident Management, E-Discovery, & Cloud Forensics": "Incident Mgmt & Forensics",
+ "Infrastructure & Virtualization Security": "Infrastructure & Virtualization",
+}
+
# Table column widths
COL_WIDTH_SMALL = 0.4 * inch
COL_WIDTH_MEDIUM = 0.9 * inch
@@ -261,6 +291,28 @@ FRAMEWORK_REGISTRY: dict[str, FrameworkConfig] = {
has_niveles=False,
has_weight=False,
),
+ "csa_ccm": FrameworkConfig(
+ name="csa_ccm",
+ display_name="CSA Cloud Controls Matrix (CCM)",
+ logo_filename=None,
+ primary_color=COLOR_BLUE,
+ secondary_color=COLOR_LIGHT_BLUE,
+ bg_color=COLOR_BG_BLUE,
+ attribute_fields=[
+ "Section",
+ "CCMLite",
+ "IaaS",
+ "PaaS",
+ "SaaS",
+ "ScopeApplicability",
+ ],
+ sections=CSA_CCM_SECTIONS,
+ language="en",
+ has_risk_levels=False,
+ has_dimensions=False,
+ has_niveles=False,
+ has_weight=False,
+ ),
}
@@ -282,5 +334,7 @@ def get_framework_config(compliance_id: str) -> FrameworkConfig | None:
return FRAMEWORK_REGISTRY["ens"]
if "nis2" in compliance_lower:
return FRAMEWORK_REGISTRY["nis2"]
+ if "csa" in compliance_lower or "ccm" in compliance_lower:
+ return FRAMEWORK_REGISTRY["csa_ccm"]
return None
diff --git a/api/src/backend/tasks/jobs/reports/csa.py b/api/src/backend/tasks/jobs/reports/csa.py
new file mode 100644
index 0000000000..c55ed198de
--- /dev/null
+++ b/api/src/backend/tasks/jobs/reports/csa.py
@@ -0,0 +1,474 @@
+from collections import defaultdict
+
+from celery.utils.log import get_task_logger
+from reportlab.lib.units import inch
+from reportlab.platypus import Image, PageBreak, Paragraph, Spacer, Table, TableStyle
+
+from api.models import StatusChoices
+
+from .base import (
+ BaseComplianceReportGenerator,
+ ComplianceData,
+ get_requirement_metadata,
+)
+from .charts import create_horizontal_bar_chart, get_chart_color_for_percentage
+from .config import (
+ COLOR_BG_BLUE,
+ COLOR_BLUE,
+ COLOR_BORDER_GRAY,
+ COLOR_DARK_GRAY,
+ COLOR_GRID_GRAY,
+ COLOR_HIGH_RISK,
+ COLOR_SAFE,
+ COLOR_WHITE,
+ CSA_CCM_SECTION_SHORT_NAMES,
+ CSA_CCM_SECTIONS,
+)
+
+logger = get_task_logger(__name__)
+
+
+class CSAReportGenerator(BaseComplianceReportGenerator):
+ """
+ PDF report generator for CSA Cloud Controls Matrix (CCM) v4.0.
+
+ This generator creates comprehensive PDF reports containing:
+ - Cover page with Prowler logo
+ - Executive summary with overall compliance score
+ - Section analysis with horizontal bar chart
+ - Section breakdown table
+ - Requirements index organized by section
+ - Detailed findings for failed requirements
+ """
+
+ def create_executive_summary(self, data: ComplianceData) -> list:
+ """
+ Create the executive summary with compliance metrics.
+
+ Args:
+ data: Aggregated compliance data.
+
+ Returns:
+ List of ReportLab elements.
+ """
+ elements = []
+
+ elements.append(Paragraph("Executive Summary", self.styles["h1"]))
+ elements.append(Spacer(1, 0.1 * inch))
+
+ # Calculate statistics
+ total = len(data.requirements)
+ passed = sum(1 for r in data.requirements if r.status == StatusChoices.PASS)
+ failed = sum(1 for r in data.requirements if r.status == StatusChoices.FAIL)
+ manual = sum(1 for r in data.requirements if r.status == StatusChoices.MANUAL)
+
+ logger.info(
+ "CSA CCM Executive Summary: total=%d, passed=%d, failed=%d, manual=%d",
+ total,
+ passed,
+ failed,
+ manual,
+ )
+
+ # Log sample of requirements for debugging
+ for req in data.requirements[:5]:
+ logger.info(
+ " Requirement %s: status=%s, passed_findings=%d, total_findings=%d",
+ req.id,
+ req.status,
+ req.passed_findings,
+ req.total_findings,
+ )
+
+ # Calculate compliance excluding manual
+ evaluated = passed + failed
+ overall_compliance = (passed / evaluated * 100) if evaluated > 0 else 100
+
+ # Summary statistics table
+ summary_data = [
+ ["Metric", "Value"],
+ ["Total Requirements", str(total)],
+ ["Passed \u2713", str(passed)],
+ ["Failed \u2717", str(failed)],
+ ["Manual \u2299", str(manual)],
+ ["Overall Compliance", f"{overall_compliance:.1f}%"],
+ ]
+
+ summary_table = Table(summary_data, colWidths=[3 * inch, 2 * inch])
+ summary_table.setStyle(
+ TableStyle(
+ [
+ ("BACKGROUND", (0, 0), (-1, 0), COLOR_BLUE),
+ ("TEXTCOLOR", (0, 0), (-1, 0), COLOR_WHITE),
+ ("BACKGROUND", (0, 2), (0, 2), COLOR_SAFE),
+ ("TEXTCOLOR", (0, 2), (0, 2), COLOR_WHITE),
+ ("BACKGROUND", (0, 3), (0, 3), COLOR_HIGH_RISK),
+ ("TEXTCOLOR", (0, 3), (0, 3), COLOR_WHITE),
+ ("BACKGROUND", (0, 4), (0, 4), COLOR_DARK_GRAY),
+ ("TEXTCOLOR", (0, 4), (0, 4), COLOR_WHITE),
+ ("ALIGN", (0, 0), (-1, -1), "CENTER"),
+ ("FONTNAME", (0, 0), (-1, 0), "PlusJakartaSans"),
+ ("FONTSIZE", (0, 0), (-1, 0), 12),
+ ("FONTSIZE", (0, 1), (-1, -1), 10),
+ ("BOTTOMPADDING", (0, 0), (-1, 0), 10),
+ ("GRID", (0, 0), (-1, -1), 0.5, COLOR_BORDER_GRAY),
+ (
+ "ROWBACKGROUNDS",
+ (1, 1),
+ (1, -1),
+ [COLOR_WHITE, COLOR_BG_BLUE],
+ ),
+ ]
+ )
+ )
+ elements.append(summary_table)
+
+ return elements
+
+ def create_charts_section(self, data: ComplianceData) -> list:
+ """
+ Create the charts section with section analysis.
+
+ Args:
+ data: Aggregated compliance data.
+
+ Returns:
+ List of ReportLab elements.
+ """
+ elements = []
+
+ # Section chart
+ elements.append(Paragraph("Compliance by Section", self.styles["h1"]))
+ elements.append(Spacer(1, 0.1 * inch))
+ elements.append(
+ Paragraph(
+ "The following chart shows compliance percentage for each domain "
+ "of the CSA Cloud Controls Matrix:",
+ self.styles["normal_center"],
+ )
+ )
+ elements.append(Spacer(1, 0.1 * inch))
+
+ chart_buffer = self._create_section_chart(data)
+ chart_buffer.seek(0)
+ chart_image = Image(chart_buffer, width=6.5 * inch, height=5 * inch)
+ elements.append(chart_image)
+ elements.append(PageBreak())
+
+ # Section breakdown table
+ elements.append(Paragraph("Section Breakdown", self.styles["h1"]))
+ elements.append(Spacer(1, 0.1 * inch))
+
+ section_table = self._create_section_table(data)
+ elements.append(section_table)
+
+ return elements
+
+ def create_requirements_index(self, data: ComplianceData) -> list:
+ """
+ Create the requirements index organized by section.
+
+ Args:
+ data: Aggregated compliance data.
+
+ Returns:
+ List of ReportLab elements.
+ """
+ elements = []
+
+ elements.append(Paragraph("Requirements Index", self.styles["h1"]))
+ elements.append(Spacer(1, 0.1 * inch))
+
+ # Organize by section
+ sections = {}
+ for req in data.requirements:
+ m = get_requirement_metadata(req.id, data.attributes_by_requirement_id)
+ if m:
+ section = getattr(m, "Section", "Other")
+
+ if section not in sections:
+ sections[section] = []
+
+ sections[section].append(
+ {
+ "id": req.id,
+ "description": req.description,
+ "status": req.status,
+ }
+ )
+
+ # Sort by CSA CCM section order
+ for section in CSA_CCM_SECTIONS:
+ if section not in sections:
+ continue
+
+ elements.append(Paragraph(section, self.styles["h2"]))
+
+ for req in sections[section]:
+ status_indicator = (
+ "\u2713" if req["status"] == StatusChoices.PASS else "\u2717"
+ )
+ if req["status"] == StatusChoices.MANUAL:
+ status_indicator = "\u2299"
+
+ desc = (
+ req["description"][:80] + "..."
+ if len(req["description"]) > 80
+ else req["description"]
+ )
+ elements.append(
+ Paragraph(
+ f"{status_indicator} {req['id']}: {desc}",
+ self.styles["normal"],
+ )
+ )
+
+ elements.append(Spacer(1, 0.1 * inch))
+
+ return elements
+
+ def _render_requirement_detail_extras(self, req, data: ComplianceData) -> list:
+ """
+ Render CSA CCM attributes in the detailed findings view.
+
+ Shows CCMLite flag, IaaS/PaaS/SaaS applicability, and
+ cross-framework references after the status badge for each requirement.
+
+ Args:
+ req: The requirement being rendered.
+ data: Aggregated compliance data.
+
+ Returns:
+ List of ReportLab elements.
+ """
+ m = get_requirement_metadata(req.id, data.attributes_by_requirement_id)
+ if not m:
+ return []
+ return self._format_requirement_attributes(m)
+
+ def _format_requirement_attributes(self, m) -> list:
+ """
+ Format CSA CCM requirement attributes as compact PDF elements.
+
+ Displays CCMLite flag, IaaS/PaaS/SaaS applicability, and
+ cross-framework references from ScopeApplicability.
+
+ Args:
+ m: Requirement metadata (CSA_CCM_Requirement_Attribute).
+
+ Returns:
+ List of ReportLab elements.
+ """
+ elements = []
+
+ # Applicability line: CCMLite | IaaS | PaaS | SaaS
+ ccm_lite = getattr(m, "CCMLite", "")
+ iaas = getattr(m, "IaaS", "")
+ paas = getattr(m, "PaaS", "")
+ saas = getattr(m, "SaaS", "")
+
+ applicability_parts = []
+ if ccm_lite:
+ applicability_parts.append(f"CCMLite: {ccm_lite}")
+ if iaas:
+ applicability_parts.append(f"IaaS: {iaas}")
+ if paas:
+ applicability_parts.append(f"PaaS: {paas}")
+ if saas:
+ applicability_parts.append(f"SaaS: {saas}")
+
+ if applicability_parts:
+ elements.append(
+ Paragraph(
+ f""
+ f"{' | '.join(applicability_parts)}"
+ f"",
+ self._attr_style(),
+ )
+ )
+
+ # ScopeApplicability references (compact)
+ scope_list = getattr(m, "ScopeApplicability", [])
+ if scope_list:
+ refs = []
+ for scope in scope_list:
+ ref_id = scope.get("ReferenceId", "") if isinstance(scope, dict) else ""
+ identifiers = (
+ scope.get("Identifiers", []) if isinstance(scope, dict) else []
+ )
+ if ref_id and identifiers:
+ ids_str = ", ".join(str(i) for i in identifiers[:4])
+ if len(identifiers) > 4:
+ ids_str += "..."
+ refs.append(f"{ref_id}: {ids_str}")
+
+ if refs:
+ refs_text = " | ".join(refs)
+ elements.append(
+ Paragraph(
+ f"{refs_text}",
+ self._attr_style(),
+ )
+ )
+
+ return elements
+
+ def _attr_style(self):
+ """
+ Return a compact style for attribute text lines.
+
+ Returns:
+ ParagraphStyle for attribute display.
+ """
+ from reportlab.lib.styles import ParagraphStyle
+
+ return ParagraphStyle(
+ "AttrLine",
+ parent=self.styles["normal"],
+ fontSize=10,
+ spaceBefore=2,
+ spaceAfter=2,
+ leftIndent=30,
+ leading=13,
+ )
+
+ def _create_section_chart(self, data: ComplianceData):
+ """
+ Create the section compliance chart.
+
+ Args:
+ data: Aggregated compliance data.
+
+ Returns:
+ BytesIO buffer containing the chart image.
+ """
+ section_scores = defaultdict(lambda: {"passed": 0, "total": 0})
+
+ no_metadata_count = 0
+ for req in data.requirements:
+ if req.status == StatusChoices.MANUAL:
+ continue
+
+ m = get_requirement_metadata(req.id, data.attributes_by_requirement_id)
+ if m:
+ section = getattr(m, "Section", "Other")
+ section_scores[section]["total"] += 1
+ if req.status == StatusChoices.PASS:
+ section_scores[section]["passed"] += 1
+ else:
+ no_metadata_count += 1
+
+ if no_metadata_count > 0:
+ logger.warning(
+ "CSA CCM chart: %d requirements had no metadata", no_metadata_count
+ )
+
+ logger.info("CSA CCM section scores:")
+ for section in CSA_CCM_SECTIONS:
+ if section in section_scores:
+ scores = section_scores[section]
+ pct = (
+ (scores["passed"] / scores["total"] * 100)
+ if scores["total"] > 0
+ else 0
+ )
+ logger.info(
+ " %s: %d/%d (%.1f%%)",
+ section,
+ scores["passed"],
+ scores["total"],
+ pct,
+ )
+
+ # Build labels and values in CSA CCM section order
+ labels = []
+ values = []
+ for section in CSA_CCM_SECTIONS:
+ if section in section_scores and section_scores[section]["total"] > 0:
+ scores = section_scores[section]
+ pct = (scores["passed"] / scores["total"]) * 100
+ # Use short name if available
+ label = CSA_CCM_SECTION_SHORT_NAMES.get(section, section)
+ labels.append(label)
+ values.append(pct)
+
+ return create_horizontal_bar_chart(
+ labels=labels,
+ values=values,
+ xlabel="Compliance (%)",
+ color_func=get_chart_color_for_percentage,
+ )
+
+ def _create_section_table(self, data: ComplianceData) -> Table:
+ """
+ Create the section breakdown table.
+
+ Args:
+ data: Aggregated compliance data.
+
+ Returns:
+ ReportLab Table element.
+ """
+ section_scores = defaultdict(lambda: {"passed": 0, "failed": 0, "manual": 0})
+
+ for req in data.requirements:
+ m = get_requirement_metadata(req.id, data.attributes_by_requirement_id)
+ if m:
+ section = getattr(m, "Section", "Other")
+
+ if req.status == StatusChoices.PASS:
+ section_scores[section]["passed"] += 1
+ elif req.status == StatusChoices.FAIL:
+ section_scores[section]["failed"] += 1
+ else:
+ section_scores[section]["manual"] += 1
+
+ table_data = [["Section", "Passed", "Failed", "Manual", "Compliance"]]
+ for section in CSA_CCM_SECTIONS:
+ if section not in section_scores:
+ continue
+ scores = section_scores[section]
+ total = scores["passed"] + scores["failed"]
+ pct = (scores["passed"] / total * 100) if total > 0 else 100
+ # Use short name if available
+ label = CSA_CCM_SECTION_SHORT_NAMES.get(section, section)
+ table_data.append(
+ [
+ label,
+ str(scores["passed"]),
+ str(scores["failed"]),
+ str(scores["manual"]),
+ f"{pct:.1f}%",
+ ]
+ )
+
+ table = Table(
+ table_data,
+ colWidths=[2.4 * inch, 0.9 * inch, 0.9 * inch, 0.9 * inch, 1.2 * inch],
+ )
+ table.setStyle(
+ TableStyle(
+ [
+ ("BACKGROUND", (0, 0), (-1, 0), COLOR_BLUE),
+ ("TEXTCOLOR", (0, 0), (-1, 0), COLOR_WHITE),
+ ("FONTNAME", (0, 0), (-1, 0), "FiraCode"),
+ ("FONTSIZE", (0, 0), (-1, 0), 10),
+ ("ALIGN", (0, 0), (-1, -1), "CENTER"),
+ ("VALIGN", (0, 0), (-1, -1), "MIDDLE"),
+ ("FONTSIZE", (0, 1), (-1, -1), 9),
+ ("GRID", (0, 0), (-1, -1), 0.5, COLOR_GRID_GRAY),
+ ("LEFTPADDING", (0, 0), (-1, -1), 6),
+ ("RIGHTPADDING", (0, 0), (-1, -1), 6),
+ ("TOPPADDING", (0, 0), (-1, -1), 4),
+ ("BOTTOMPADDING", (0, 0), (-1, -1), 4),
+ (
+ "ROWBACKGROUNDS",
+ (0, 1),
+ (-1, -1),
+ [COLOR_WHITE, COLOR_BG_BLUE],
+ ),
+ ]
+ )
+ )
+
+ return table
diff --git a/api/src/backend/tasks/jobs/threatscore_utils.py b/api/src/backend/tasks/jobs/threatscore_utils.py
index c46c279bf4..7d0f2b6ec3 100644
--- a/api/src/backend/tasks/jobs/threatscore_utils.py
+++ b/api/src/backend/tasks/jobs/threatscore_utils.py
@@ -114,6 +114,11 @@ def _calculate_requirements_data_from_statistics(
requirement_status = StatusChoices.PASS
else:
requirement_status = StatusChoices.FAIL
+ elif requirement_checks:
+ # Requirement has checks but none produced findings — consistent
+ # with the dashboard's scan processing which treats this as PASS
+ # (no failed checks means the requirement is considered compliant).
+ requirement_status = StatusChoices.PASS
else:
requirement_status = StatusChoices.MANUAL
diff --git a/api/src/backend/tasks/tasks.py b/api/src/backend/tasks/tasks.py
index 0dd3b0905b..30cc0b09c4 100644
--- a/api/src/backend/tasks/tasks.py
+++ b/api/src/backend/tasks/tasks.py
@@ -11,6 +11,7 @@ from django_celery_beat.models import PeriodicTask
from tasks.jobs.attack_paths import (
attack_paths_scan,
can_provider_run_attack_paths_scan,
+ db_utils as attack_paths_db_utils,
)
from tasks.jobs.backfill import (
backfill_compliance_summaries,
@@ -359,8 +360,25 @@ def perform_scan_summary_task(tenant_id: str, scan_id: str):
return aggregate_findings(tenant_id=tenant_id, scan_id=scan_id)
+class AttackPathsScanRLSTask(RLSTask):
+ """
+ RLS task that marks the `AttackPathsScan` DB row as `FAILED` when the Celery task fails.
+
+ Covers failures that happen outside the job's own try/except (e.g. provider lookup,
+ SDK initialization, or Neo4j configuration errors during setup).
+ """
+
+ def on_failure(self, exc, task_id, args, kwargs, _einfo):
+ tenant_id = kwargs.get("tenant_id")
+ scan_id = kwargs.get("scan_id")
+
+ if tenant_id and scan_id:
+ logger.error(f"Attack paths scan task {task_id} failed: {exc}")
+ attack_paths_db_utils.fail_attack_paths_scan(tenant_id, scan_id, str(exc))
+
+
@shared_task(
- base=RLSTask,
+ base=AttackPathsScanRLSTask,
bind=True,
name="attack-paths-scan-perform",
queue="attack-paths-scans",
@@ -888,11 +906,11 @@ def jira_integration_task(
@handle_provider_deletion
def generate_compliance_reports_task(tenant_id: str, scan_id: str, provider_id: str):
"""
- Optimized task to generate ThreatScore, ENS, and NIS2 reports with shared queries.
+ Optimized task to generate ThreatScore, ENS, NIS2, and CSA CCM reports with shared queries.
This task is more efficient than running separate report tasks because it reuses database queries:
- - Provider object fetched once (instead of three times)
- - Requirement statistics aggregated once (instead of three times)
+ - Provider object fetched once (instead of multiple times)
+ - Requirement statistics aggregated once (instead of multiple times)
- Can reduce database load by up to 50-70%
Args:
@@ -910,6 +928,7 @@ def generate_compliance_reports_task(tenant_id: str, scan_id: str, provider_id:
generate_threatscore=True,
generate_ens=True,
generate_nis2=True,
+ generate_csa=True,
)
diff --git a/api/src/backend/tasks/tests/test_attack_paths_scan.py b/api/src/backend/tasks/tests/test_attack_paths_scan.py
index ebee87c981..a883360f5e 100644
--- a/api/src/backend/tasks/tests/test_attack_paths_scan.py
+++ b/api/src/backend/tasks/tests/test_attack_paths_scan.py
@@ -4,6 +4,7 @@ from unittest.mock import MagicMock, call, patch
import pytest
from tasks.jobs.attack_paths import findings as findings_module
+from tasks.jobs.attack_paths import internet as internet_module
from tasks.jobs.attack_paths.scan import run as attack_paths_run
from api.models import (
@@ -27,16 +28,15 @@ class TestAttackPathsRun:
"tasks.jobs.attack_paths.scan.utils.call_within_event_loop",
side_effect=lambda fn, *a, **kw: fn(*a, **kw),
)
- @patch(
- "tasks.jobs.attack_paths.scan.db_utils.get_old_attack_paths_scans",
- return_value=[],
- )
+ @patch("tasks.jobs.attack_paths.scan.db_utils.set_graph_data_ready")
+ @patch("tasks.jobs.attack_paths.scan.db_utils.set_provider_graph_data_ready")
@patch("tasks.jobs.attack_paths.scan.db_utils.finish_attack_paths_scan")
@patch("tasks.jobs.attack_paths.scan.db_utils.update_attack_paths_scan_progress")
@patch("tasks.jobs.attack_paths.scan.db_utils.starting_attack_paths_scan")
@patch("tasks.jobs.attack_paths.scan.sync.sync_graph")
@patch("tasks.jobs.attack_paths.scan.graph_database.drop_subgraph")
@patch("tasks.jobs.attack_paths.scan.sync.create_sync_indexes")
+ @patch("tasks.jobs.attack_paths.scan.internet.analysis")
@patch("tasks.jobs.attack_paths.scan.findings.analysis")
@patch("tasks.jobs.attack_paths.scan.findings.create_findings_indexes")
@patch("tasks.jobs.attack_paths.scan.cartography_ontology.run")
@@ -67,13 +67,15 @@ class TestAttackPathsRun:
mock_cartography_ontology,
mock_findings_indexes,
mock_findings_analysis,
+ mock_internet_analysis,
mock_sync_indexes,
mock_drop_subgraph,
mock_sync,
mock_starting,
mock_update_progress,
mock_finish,
- mock_get_old_scans,
+ mock_set_provider_graph_data_ready,
+ mock_set_graph_data_ready,
mock_event_loop,
mock_drop_db,
tenants_fixture,
@@ -139,6 +141,7 @@ class TestAttackPathsRun:
# These use tmp_cartography_config (neo4j_database="db-scan-id")
mock_cartography_analysis.assert_called_once()
mock_cartography_ontology.assert_called_once()
+ mock_internet_analysis.assert_called_once()
mock_findings_analysis.assert_called_once()
mock_drop_subgraph.assert_called_once_with(
database="tenant-db",
@@ -160,9 +163,66 @@ class TestAttackPathsRun:
mock_finish.assert_called_once_with(
attack_paths_scan, StateChoices.COMPLETED, ingestion_result
)
+ mock_set_provider_graph_data_ready.assert_called_once_with(
+ attack_paths_scan, False
+ )
+ mock_set_graph_data_ready.assert_called_once_with(attack_paths_scan, True)
+ @patch(
+ "tasks.jobs.attack_paths.scan.utils.stringify_exception",
+ return_value="Cartography failed: ingestion boom",
+ )
+ @patch(
+ "tasks.jobs.attack_paths.scan.utils.call_within_event_loop",
+ side_effect=lambda fn, *a, **kw: fn(*a, **kw),
+ )
+ @patch("tasks.jobs.attack_paths.scan.graph_database.drop_database")
+ @patch("tasks.jobs.attack_paths.scan.db_utils.finish_attack_paths_scan")
+ @patch("tasks.jobs.attack_paths.scan.db_utils.set_graph_data_ready")
+ @patch("tasks.jobs.attack_paths.scan.db_utils.set_provider_graph_data_ready")
+ @patch("tasks.jobs.attack_paths.scan.db_utils.update_attack_paths_scan_progress")
+ @patch("tasks.jobs.attack_paths.scan.db_utils.starting_attack_paths_scan")
+ @patch("tasks.jobs.attack_paths.scan.findings.analysis")
+ @patch("tasks.jobs.attack_paths.scan.internet.analysis")
+ @patch("tasks.jobs.attack_paths.scan.findings.create_findings_indexes")
+ @patch("tasks.jobs.attack_paths.scan.cartography_analysis.run")
+ @patch("tasks.jobs.attack_paths.scan.cartography_create_indexes.run")
+ @patch("tasks.jobs.attack_paths.scan.graph_database.create_database")
+ @patch(
+ "tasks.jobs.attack_paths.scan.graph_database.get_database_name",
+ return_value="db-scan-id",
+ )
+ @patch("tasks.jobs.attack_paths.scan.graph_database.get_uri")
+ @patch(
+ "tasks.jobs.attack_paths.scan.initialize_prowler_provider",
+ return_value=MagicMock(_enabled_regions=["us-east-1"]),
+ )
+ @patch(
+ "tasks.jobs.attack_paths.scan.rls_transaction",
+ new=lambda *args, **kwargs: nullcontext(),
+ )
def test_run_failure_marks_scan_failed(
- self, tenants_fixture, providers_fixture, scans_fixture
+ self,
+ mock_init_provider,
+ mock_get_uri,
+ mock_get_db_name,
+ mock_create_db,
+ mock_cartography_indexes,
+ mock_cartography_analysis,
+ mock_findings_indexes,
+ mock_internet_analysis,
+ mock_findings_analysis,
+ mock_starting,
+ mock_update_progress,
+ mock_set_provider_graph_data_ready,
+ mock_set_graph_data_ready,
+ mock_finish,
+ mock_drop_db,
+ mock_event_loop,
+ mock_stringify,
+ tenants_fixture,
+ providers_fixture,
+ scans_fixture,
):
tenant = tenants_fixture[0]
provider = providers_fixture[0]
@@ -186,52 +246,18 @@ class TestAttackPathsRun:
ingestion_fn = MagicMock(side_effect=RuntimeError("ingestion boom"))
with (
- patch(
- "tasks.jobs.attack_paths.scan.rls_transaction",
- new=lambda *args, **kwargs: nullcontext(),
- ),
- patch(
- "tasks.jobs.attack_paths.scan.initialize_prowler_provider",
- return_value=MagicMock(_enabled_regions=["us-east-1"]),
- ),
- patch("tasks.jobs.attack_paths.scan.graph_database.get_uri"),
- patch(
- "tasks.jobs.attack_paths.scan.graph_database.get_database_name",
- return_value="db-scan-id",
- ),
- patch("tasks.jobs.attack_paths.scan.graph_database.create_database"),
patch(
"tasks.jobs.attack_paths.scan.graph_database.get_session",
return_value=session_ctx,
),
- patch("tasks.jobs.attack_paths.scan.cartography_create_indexes.run"),
- patch("tasks.jobs.attack_paths.scan.cartography_analysis.run"),
- patch("tasks.jobs.attack_paths.scan.findings.create_findings_indexes"),
- patch("tasks.jobs.attack_paths.scan.findings.analysis"),
patch(
"tasks.jobs.attack_paths.scan.db_utils.retrieve_attack_paths_scan",
return_value=attack_paths_scan,
),
- patch("tasks.jobs.attack_paths.scan.db_utils.starting_attack_paths_scan"),
- patch(
- "tasks.jobs.attack_paths.scan.db_utils.update_attack_paths_scan_progress"
- ),
- patch(
- "tasks.jobs.attack_paths.scan.db_utils.finish_attack_paths_scan"
- ) as mock_finish,
- patch("tasks.jobs.attack_paths.scan.graph_database.drop_database"),
patch(
"tasks.jobs.attack_paths.scan.get_cartography_ingestion_function",
return_value=ingestion_fn,
),
- patch(
- "tasks.jobs.attack_paths.scan.utils.call_within_event_loop",
- side_effect=lambda fn, *a, **kw: fn(*a, **kw),
- ),
- patch(
- "tasks.jobs.attack_paths.scan.utils.stringify_exception",
- return_value="Cartography failed: ingestion boom",
- ),
):
with pytest.raises(RuntimeError, match="ingestion boom"):
attack_paths_run(str(tenant.id), str(scan.id), "task-456")
@@ -239,9 +265,109 @@ class TestAttackPathsRun:
failure_args = mock_finish.call_args[0]
assert failure_args[0] is attack_paths_scan
assert failure_args[1] == StateChoices.FAILED
- assert failure_args[2] == {
- "global_cartography_error": "Cartography failed: ingestion boom"
- }
+ assert failure_args[2] == {"global_error": "Cartography failed: ingestion boom"}
+
+ @patch(
+ "tasks.jobs.attack_paths.scan.utils.stringify_exception",
+ return_value="Cartography failed: ingestion boom",
+ )
+ @patch(
+ "tasks.jobs.attack_paths.scan.utils.call_within_event_loop",
+ side_effect=lambda fn, *a, **kw: fn(*a, **kw),
+ )
+ @patch(
+ "tasks.jobs.attack_paths.scan.graph_database.drop_database",
+ side_effect=ConnectionError("neo4j down"),
+ )
+ @patch("tasks.jobs.attack_paths.scan.db_utils.finish_attack_paths_scan")
+ @patch("tasks.jobs.attack_paths.scan.db_utils.set_graph_data_ready")
+ @patch("tasks.jobs.attack_paths.scan.db_utils.set_provider_graph_data_ready")
+ @patch("tasks.jobs.attack_paths.scan.db_utils.update_attack_paths_scan_progress")
+ @patch("tasks.jobs.attack_paths.scan.db_utils.starting_attack_paths_scan")
+ @patch("tasks.jobs.attack_paths.scan.findings.analysis")
+ @patch("tasks.jobs.attack_paths.scan.internet.analysis")
+ @patch("tasks.jobs.attack_paths.scan.findings.create_findings_indexes")
+ @patch("tasks.jobs.attack_paths.scan.cartography_analysis.run")
+ @patch("tasks.jobs.attack_paths.scan.cartography_create_indexes.run")
+ @patch("tasks.jobs.attack_paths.scan.graph_database.create_database")
+ @patch(
+ "tasks.jobs.attack_paths.scan.graph_database.get_database_name",
+ return_value="db-scan-id",
+ )
+ @patch("tasks.jobs.attack_paths.scan.graph_database.get_uri")
+ @patch(
+ "tasks.jobs.attack_paths.scan.initialize_prowler_provider",
+ return_value=MagicMock(_enabled_regions=["us-east-1"]),
+ )
+ @patch(
+ "tasks.jobs.attack_paths.scan.rls_transaction",
+ new=lambda *args, **kwargs: nullcontext(),
+ )
+ def test_run_failure_marks_scan_failed_even_when_drop_database_fails(
+ self,
+ mock_init_provider,
+ mock_get_uri,
+ mock_get_db_name,
+ mock_create_db,
+ mock_cartography_indexes,
+ mock_cartography_analysis,
+ mock_findings_indexes,
+ mock_internet_analysis,
+ mock_findings_analysis,
+ mock_starting,
+ mock_update_progress,
+ mock_set_provider_graph_data_ready,
+ mock_set_graph_data_ready,
+ mock_finish,
+ mock_drop_db,
+ mock_event_loop,
+ mock_stringify,
+ tenants_fixture,
+ providers_fixture,
+ scans_fixture,
+ ):
+ tenant = tenants_fixture[0]
+ provider = providers_fixture[0]
+ provider.provider = Provider.ProviderChoices.AWS
+ provider.save()
+ scan = scans_fixture[0]
+ scan.provider = provider
+ scan.save()
+
+ attack_paths_scan = AttackPathsScan.objects.create(
+ tenant_id=tenant.id,
+ provider=provider,
+ scan=scan,
+ state=StateChoices.SCHEDULED,
+ )
+
+ mock_session = MagicMock()
+ session_ctx = MagicMock()
+ session_ctx.__enter__.return_value = mock_session
+ session_ctx.__exit__.return_value = False
+ ingestion_fn = MagicMock(side_effect=RuntimeError("ingestion boom"))
+
+ with (
+ patch(
+ "tasks.jobs.attack_paths.scan.graph_database.get_session",
+ return_value=session_ctx,
+ ),
+ patch(
+ "tasks.jobs.attack_paths.scan.db_utils.retrieve_attack_paths_scan",
+ return_value=attack_paths_scan,
+ ),
+ patch(
+ "tasks.jobs.attack_paths.scan.get_cartography_ingestion_function",
+ return_value=ingestion_fn,
+ ),
+ ):
+ with pytest.raises(RuntimeError, match="ingestion boom"):
+ attack_paths_run(str(tenant.id), str(scan.id), "task-789")
+
+ failure_args = mock_finish.call_args[0]
+ assert failure_args[0] is attack_paths_scan
+ assert failure_args[1] == StateChoices.FAILED
+ assert failure_args[2] == {"global_error": "Cartography failed: ingestion boom"}
def test_run_returns_early_for_unsupported_provider(self, tenants_fixture):
tenant = tenants_fixture[0]
@@ -286,6 +412,194 @@ class TestAttackPathsRun:
mock_retrieve.assert_called_once_with(str(tenant.id), str(scan.id))
+@pytest.mark.django_db
+class TestFailAttackPathsScan:
+ def test_marks_executing_scan_as_failed(
+ self, tenants_fixture, providers_fixture, scans_fixture
+ ):
+ from tasks.jobs.attack_paths.db_utils import (
+ fail_attack_paths_scan,
+ )
+
+ tenant = tenants_fixture[0]
+ provider = providers_fixture[0]
+ provider.provider = Provider.ProviderChoices.AWS
+ provider.save()
+ scan = scans_fixture[0]
+ scan.provider = provider
+ scan.save()
+
+ attack_paths_scan = AttackPathsScan.objects.create(
+ tenant_id=tenant.id,
+ provider=provider,
+ scan=scan,
+ state=StateChoices.EXECUTING,
+ )
+
+ with (
+ patch(
+ "tasks.jobs.attack_paths.db_utils.retrieve_attack_paths_scan",
+ return_value=attack_paths_scan,
+ ) as mock_retrieve,
+ patch(
+ "tasks.jobs.attack_paths.db_utils.graph_database.drop_database"
+ ) as mock_drop_db,
+ patch(
+ "tasks.jobs.attack_paths.db_utils.finish_attack_paths_scan"
+ ) as mock_finish,
+ ):
+ fail_attack_paths_scan(str(tenant.id), str(scan.id), "setup exploded")
+
+ mock_retrieve.assert_called_once_with(str(tenant.id), str(scan.id))
+ expected_tmp_db = f"db-tmp-scan-{str(attack_paths_scan.id).lower()}"
+ mock_drop_db.assert_called_once_with(expected_tmp_db)
+ mock_finish.assert_called_once_with(
+ attack_paths_scan,
+ StateChoices.FAILED,
+ {"global_error": "setup exploded"},
+ )
+
+ def test_drops_temp_database_even_when_drop_fails(
+ self, tenants_fixture, providers_fixture, scans_fixture
+ ):
+ from tasks.jobs.attack_paths.db_utils import (
+ fail_attack_paths_scan,
+ )
+
+ tenant = tenants_fixture[0]
+ provider = providers_fixture[0]
+ provider.provider = Provider.ProviderChoices.AWS
+ provider.save()
+ scan = scans_fixture[0]
+ scan.provider = provider
+ scan.save()
+
+ attack_paths_scan = AttackPathsScan.objects.create(
+ tenant_id=tenant.id,
+ provider=provider,
+ scan=scan,
+ state=StateChoices.EXECUTING,
+ )
+
+ with (
+ patch(
+ "tasks.jobs.attack_paths.db_utils.retrieve_attack_paths_scan",
+ return_value=attack_paths_scan,
+ ),
+ patch(
+ "tasks.jobs.attack_paths.db_utils.graph_database.drop_database",
+ side_effect=Exception("Neo4j unreachable"),
+ ),
+ patch(
+ "tasks.jobs.attack_paths.db_utils.finish_attack_paths_scan"
+ ) as mock_finish,
+ ):
+ fail_attack_paths_scan(str(tenant.id), str(scan.id), "setup exploded")
+
+ mock_finish.assert_called_once_with(
+ attack_paths_scan,
+ StateChoices.FAILED,
+ {"global_error": "setup exploded"},
+ )
+
+ def test_skips_already_failed_scan(
+ self, tenants_fixture, providers_fixture, scans_fixture
+ ):
+ from tasks.jobs.attack_paths.db_utils import (
+ fail_attack_paths_scan,
+ )
+
+ tenant = tenants_fixture[0]
+ provider = providers_fixture[0]
+ provider.provider = Provider.ProviderChoices.AWS
+ provider.save()
+ scan = scans_fixture[0]
+ scan.provider = provider
+ scan.save()
+
+ attack_paths_scan = AttackPathsScan.objects.create(
+ tenant_id=tenant.id,
+ provider=provider,
+ scan=scan,
+ state=StateChoices.FAILED,
+ )
+
+ with (
+ patch(
+ "tasks.jobs.attack_paths.db_utils.retrieve_attack_paths_scan",
+ return_value=attack_paths_scan,
+ ),
+ patch(
+ "tasks.jobs.attack_paths.db_utils.graph_database.drop_database"
+ ) as mock_drop_db,
+ patch(
+ "tasks.jobs.attack_paths.db_utils.finish_attack_paths_scan"
+ ) as mock_finish,
+ ):
+ fail_attack_paths_scan(str(tenant.id), str(scan.id), "setup exploded")
+
+ mock_drop_db.assert_not_called()
+ mock_finish.assert_not_called()
+
+ def test_skips_when_no_scan_found(self, tenants_fixture):
+ from tasks.jobs.attack_paths.db_utils import (
+ fail_attack_paths_scan,
+ )
+
+ tenant = tenants_fixture[0]
+
+ with (
+ patch(
+ "tasks.jobs.attack_paths.db_utils.retrieve_attack_paths_scan",
+ return_value=None,
+ ),
+ patch(
+ "tasks.jobs.attack_paths.db_utils.finish_attack_paths_scan"
+ ) as mock_finish,
+ ):
+ fail_attack_paths_scan(str(tenant.id), "nonexistent", "setup exploded")
+
+ mock_finish.assert_not_called()
+
+
+class TestAttackPathsScanRLSTaskOnFailure:
+ def test_on_failure_delegates_to_fail_attack_paths_scan(self):
+ from tasks.tasks import AttackPathsScanRLSTask
+
+ task = AttackPathsScanRLSTask()
+
+ with patch(
+ "tasks.tasks.attack_paths_db_utils.fail_attack_paths_scan"
+ ) as mock_fail:
+ task.on_failure(
+ exc=RuntimeError("boom"),
+ task_id="task-abc",
+ args=(),
+ kwargs={"tenant_id": "t-1", "scan_id": "s-1"},
+ _einfo=None,
+ )
+
+ mock_fail.assert_called_once_with("t-1", "s-1", "boom")
+
+ def test_on_failure_skips_when_missing_kwargs(self):
+ from tasks.tasks import AttackPathsScanRLSTask
+
+ task = AttackPathsScanRLSTask()
+
+ with patch(
+ "tasks.tasks.attack_paths_db_utils.fail_attack_paths_scan"
+ ) as mock_fail:
+ task.on_failure(
+ exc=RuntimeError("boom"),
+ task_id="task-abc",
+ args=(),
+ kwargs={},
+ _einfo=None,
+ )
+
+ mock_fail.assert_not_called()
+
+
@pytest.mark.django_db
class TestAttackPathsFindingsHelpers:
def test_create_findings_indexes_executes_all_statements(self):
@@ -757,3 +1071,359 @@ class TestAttackPathsFindingsHelpers:
findings_module.load_findings(mock_session, empty_gen(), provider, config)
mock_session.run.assert_not_called()
+
+
+class TestInternetAnalysis:
+ def _make_provider_and_config(self):
+ provider = MagicMock()
+ provider.provider = "aws"
+ provider.uid = "123456789012"
+ config = SimpleNamespace(update_tag=1234567890)
+ return provider, config
+
+ def test_analysis_creates_node_and_relationships(self):
+ """Verify both Cypher statements are executed and relationship count returned."""
+ mock_session = MagicMock()
+ mock_result = MagicMock()
+ mock_result.single.return_value = {"relationships_merged": 3}
+ mock_session.run.side_effect = [None, mock_result]
+ provider, config = self._make_provider_and_config()
+
+ with patch(
+ "tasks.jobs.attack_paths.internet.get_root_node_label",
+ return_value="AWSAccount",
+ ):
+ result = internet_module.analysis(mock_session, provider, config)
+
+ assert mock_session.run.call_count == 2
+ assert result == 3
+
+ def test_analysis_zero_exposed_resources(self):
+ """When no resources are exposed, zero relationships are created."""
+ mock_session = MagicMock()
+ mock_result = MagicMock()
+ mock_result.single.return_value = {"relationships_merged": 0}
+ mock_session.run.side_effect = [None, mock_result]
+ provider, config = self._make_provider_and_config()
+
+ with patch(
+ "tasks.jobs.attack_paths.internet.get_root_node_label",
+ return_value="AWSAccount",
+ ):
+ result = internet_module.analysis(mock_session, provider, config)
+
+ assert result == 0
+
+
+@pytest.mark.django_db
+class TestAttackPathsDbUtilsGraphDataReady:
+ """Tests for db_utils functions related to graph_data_ready lifecycle."""
+
+ def test_create_attack_paths_scan_first_scan_defaults_to_false(
+ self, tenants_fixture, providers_fixture, scans_fixture
+ ):
+ from tasks.jobs.attack_paths.db_utils import create_attack_paths_scan
+
+ tenant = tenants_fixture[0]
+ provider = providers_fixture[0]
+ provider.provider = Provider.ProviderChoices.AWS
+ provider.save()
+ scan = scans_fixture[0]
+ scan.provider = provider
+ scan.save()
+
+ with patch(
+ "tasks.jobs.attack_paths.db_utils.rls_transaction",
+ new=lambda *args, **kwargs: nullcontext(),
+ ):
+ attack_paths_scan = create_attack_paths_scan(
+ str(tenant.id), str(scan.id), provider.id
+ )
+
+ assert attack_paths_scan is not None
+ assert attack_paths_scan.graph_data_ready is False
+
+ def test_create_attack_paths_scan_inherits_true_from_previous(
+ self, tenants_fixture, providers_fixture, scans_fixture
+ ):
+ from tasks.jobs.attack_paths.db_utils import create_attack_paths_scan
+
+ tenant = tenants_fixture[0]
+ provider = providers_fixture[0]
+ provider.provider = Provider.ProviderChoices.AWS
+ provider.save()
+ scan = scans_fixture[0]
+ scan.provider = provider
+ scan.save()
+
+ AttackPathsScan.objects.create(
+ tenant_id=tenant.id,
+ provider=provider,
+ scan=scan,
+ state=StateChoices.COMPLETED,
+ graph_data_ready=True,
+ )
+
+ new_scan = Scan.objects.create(
+ name="New Scan",
+ provider=provider,
+ trigger=Scan.TriggerChoices.MANUAL,
+ state=StateChoices.AVAILABLE,
+ tenant_id=tenant.id,
+ )
+
+ with patch(
+ "tasks.jobs.attack_paths.db_utils.rls_transaction",
+ new=lambda *args, **kwargs: nullcontext(),
+ ):
+ attack_paths_scan = create_attack_paths_scan(
+ str(tenant.id), str(new_scan.id), provider.id
+ )
+
+ assert attack_paths_scan is not None
+ assert attack_paths_scan.graph_data_ready is True
+
+ def test_create_attack_paths_scan_inherits_false_when_no_previous_ready(
+ self, tenants_fixture, providers_fixture, scans_fixture
+ ):
+ from tasks.jobs.attack_paths.db_utils import create_attack_paths_scan
+
+ tenant = tenants_fixture[0]
+ provider = providers_fixture[0]
+ provider.provider = Provider.ProviderChoices.AWS
+ provider.save()
+ scan = scans_fixture[0]
+ scan.provider = provider
+ scan.save()
+
+ AttackPathsScan.objects.create(
+ tenant_id=tenant.id,
+ provider=provider,
+ scan=scan,
+ state=StateChoices.FAILED,
+ graph_data_ready=False,
+ )
+
+ new_scan = Scan.objects.create(
+ name="New Scan",
+ provider=provider,
+ trigger=Scan.TriggerChoices.MANUAL,
+ state=StateChoices.AVAILABLE,
+ tenant_id=tenant.id,
+ )
+
+ with patch(
+ "tasks.jobs.attack_paths.db_utils.rls_transaction",
+ new=lambda *args, **kwargs: nullcontext(),
+ ):
+ attack_paths_scan = create_attack_paths_scan(
+ str(tenant.id), str(new_scan.id), provider.id
+ )
+
+ assert attack_paths_scan is not None
+ assert attack_paths_scan.graph_data_ready is False
+
+ def test_set_graph_data_ready_updates_field(
+ self, tenants_fixture, providers_fixture, scans_fixture
+ ):
+ from tasks.jobs.attack_paths.db_utils import set_graph_data_ready
+
+ tenant = tenants_fixture[0]
+ provider = providers_fixture[0]
+ provider.provider = Provider.ProviderChoices.AWS
+ provider.save()
+ scan = scans_fixture[0]
+ scan.provider = provider
+ scan.save()
+
+ attack_paths_scan = AttackPathsScan.objects.create(
+ tenant_id=tenant.id,
+ provider=provider,
+ scan=scan,
+ state=StateChoices.EXECUTING,
+ graph_data_ready=True,
+ )
+
+ with patch(
+ "tasks.jobs.attack_paths.db_utils.rls_transaction",
+ new=lambda *args, **kwargs: nullcontext(),
+ ):
+ set_graph_data_ready(attack_paths_scan, False)
+
+ attack_paths_scan.refresh_from_db()
+ assert attack_paths_scan.graph_data_ready is False
+
+ with patch(
+ "tasks.jobs.attack_paths.db_utils.rls_transaction",
+ new=lambda *args, **kwargs: nullcontext(),
+ ):
+ set_graph_data_ready(attack_paths_scan, True)
+
+ attack_paths_scan.refresh_from_db()
+ assert attack_paths_scan.graph_data_ready is True
+
+ def test_finish_attack_paths_scan_does_not_modify_graph_data_ready(
+ self, tenants_fixture, providers_fixture, scans_fixture
+ ):
+ from tasks.jobs.attack_paths.db_utils import finish_attack_paths_scan
+
+ tenant = tenants_fixture[0]
+ provider = providers_fixture[0]
+ provider.provider = Provider.ProviderChoices.AWS
+ provider.save()
+ scan = scans_fixture[0]
+ scan.provider = provider
+ scan.save()
+
+ attack_paths_scan = AttackPathsScan.objects.create(
+ tenant_id=tenant.id,
+ provider=provider,
+ scan=scan,
+ state=StateChoices.EXECUTING,
+ graph_data_ready=True,
+ )
+
+ with patch(
+ "tasks.jobs.attack_paths.db_utils.rls_transaction",
+ new=lambda *args, **kwargs: nullcontext(),
+ ):
+ finish_attack_paths_scan(attack_paths_scan, StateChoices.COMPLETED, {})
+
+ attack_paths_scan.refresh_from_db()
+ assert attack_paths_scan.state == StateChoices.COMPLETED
+ assert attack_paths_scan.graph_data_ready is True
+
+ def test_finish_attack_paths_scan_preserves_graph_data_ready_on_failure(
+ self, tenants_fixture, providers_fixture, scans_fixture
+ ):
+ from tasks.jobs.attack_paths.db_utils import finish_attack_paths_scan
+
+ tenant = tenants_fixture[0]
+ provider = providers_fixture[0]
+ provider.provider = Provider.ProviderChoices.AWS
+ provider.save()
+ scan = scans_fixture[0]
+ scan.provider = provider
+ scan.save()
+
+ attack_paths_scan = AttackPathsScan.objects.create(
+ tenant_id=tenant.id,
+ provider=provider,
+ scan=scan,
+ state=StateChoices.EXECUTING,
+ graph_data_ready=True,
+ )
+
+ with patch(
+ "tasks.jobs.attack_paths.db_utils.rls_transaction",
+ new=lambda *args, **kwargs: nullcontext(),
+ ):
+ finish_attack_paths_scan(
+ attack_paths_scan,
+ StateChoices.FAILED,
+ {"global_error": "boom"},
+ )
+
+ attack_paths_scan.refresh_from_db()
+ assert attack_paths_scan.state == StateChoices.FAILED
+ assert attack_paths_scan.graph_data_ready is True
+
+ def test_set_provider_graph_data_ready_updates_all_scans_for_provider(
+ self, tenants_fixture, providers_fixture, scans_fixture
+ ):
+ from tasks.jobs.attack_paths.db_utils import set_provider_graph_data_ready
+
+ tenant = tenants_fixture[0]
+ provider = providers_fixture[0]
+ provider.provider = Provider.ProviderChoices.AWS
+ provider.save()
+
+ scan_a = scans_fixture[0]
+ scan_a.provider = provider
+ scan_a.save()
+
+ scan_b = Scan.objects.create(
+ name="Second Scan",
+ provider=provider,
+ trigger=Scan.TriggerChoices.MANUAL,
+ state=StateChoices.AVAILABLE,
+ tenant_id=tenant.id,
+ )
+
+ old_ap_scan = AttackPathsScan.objects.create(
+ tenant_id=tenant.id,
+ provider=provider,
+ scan=scan_a,
+ state=StateChoices.COMPLETED,
+ graph_data_ready=True,
+ )
+ new_ap_scan = AttackPathsScan.objects.create(
+ tenant_id=tenant.id,
+ provider=provider,
+ scan=scan_b,
+ state=StateChoices.EXECUTING,
+ graph_data_ready=True,
+ )
+
+ with patch(
+ "tasks.jobs.attack_paths.db_utils.rls_transaction",
+ new=lambda *args, **kwargs: nullcontext(),
+ ):
+ set_provider_graph_data_ready(new_ap_scan, False)
+
+ old_ap_scan.refresh_from_db()
+ new_ap_scan.refresh_from_db()
+ assert old_ap_scan.graph_data_ready is False
+ assert new_ap_scan.graph_data_ready is False
+
+ def test_set_provider_graph_data_ready_does_not_affect_other_providers(
+ self, tenants_fixture, providers_fixture, scans_fixture
+ ):
+ from tasks.jobs.attack_paths.db_utils import set_provider_graph_data_ready
+
+ tenant = tenants_fixture[0]
+ provider_a = providers_fixture[0]
+ provider_a.provider = Provider.ProviderChoices.AWS
+ provider_a.save()
+
+ provider_b = providers_fixture[1]
+ provider_b.provider = Provider.ProviderChoices.AWS
+ provider_b.save()
+
+ scan_a = scans_fixture[0]
+ scan_a.provider = provider_a
+ scan_a.save()
+
+ scan_b = Scan.objects.create(
+ name="Scan for provider B",
+ provider=provider_b,
+ trigger=Scan.TriggerChoices.MANUAL,
+ state=StateChoices.COMPLETED,
+ tenant_id=tenant.id,
+ )
+
+ ap_scan_a = AttackPathsScan.objects.create(
+ tenant_id=tenant.id,
+ provider=provider_a,
+ scan=scan_a,
+ state=StateChoices.EXECUTING,
+ graph_data_ready=True,
+ )
+ ap_scan_b = AttackPathsScan.objects.create(
+ tenant_id=tenant.id,
+ provider=provider_b,
+ scan=scan_b,
+ state=StateChoices.COMPLETED,
+ graph_data_ready=True,
+ )
+
+ with patch(
+ "tasks.jobs.attack_paths.db_utils.rls_transaction",
+ new=lambda *args, **kwargs: nullcontext(),
+ ):
+ set_provider_graph_data_ready(ap_scan_a, False)
+
+ ap_scan_a.refresh_from_db()
+ ap_scan_b.refresh_from_db()
+ assert ap_scan_a.graph_data_ready is False
+ assert ap_scan_b.graph_data_ready is True
diff --git a/api/src/backend/tasks/tests/test_deletion.py b/api/src/backend/tasks/tests/test_deletion.py
index 843ccb5df8..831ba20641 100644
--- a/api/src/backend/tasks/tests/test_deletion.py
+++ b/api/src/backend/tasks/tests/test_deletion.py
@@ -4,6 +4,7 @@ import pytest
from django.core.exceptions import ObjectDoesNotExist
+from api.attack_paths import database as graph_database
from api.models import Provider, Tenant
from tasks.jobs.deletion import delete_provider, delete_tenant
@@ -47,14 +48,61 @@ class TestDeleteProvider:
tenant_id = str(tenants_fixture[0].id)
non_existent_pk = "babf6796-cfcc-4fd3-9dcf-88d012247645"
- with pytest.raises(ObjectDoesNotExist):
- delete_provider(tenant_id, non_existent_pk)
+ result = delete_provider(tenant_id, non_existent_pk)
- mock_get_database_name.assert_called_once_with(tenant_id)
- mock_drop_subgraph.assert_called_once_with(
- "tenant-db",
- non_existent_pk,
- )
+ assert result == {}
+ mock_get_database_name.assert_not_called()
+ mock_drop_subgraph.assert_not_called()
+
+ def test_delete_provider_drops_temp_attack_paths_databases(
+ self, providers_fixture, create_attack_paths_scan
+ ):
+ instance = providers_fixture[0]
+ tenant_id = str(instance.tenant_id)
+
+ aps1 = create_attack_paths_scan(instance)
+ aps2 = create_attack_paths_scan(instance)
+
+ with (
+ patch(
+ "tasks.jobs.deletion.graph_database.drop_subgraph",
+ ),
+ patch(
+ "tasks.jobs.deletion.graph_database.drop_database",
+ ) as mock_drop_database,
+ ):
+ result = delete_provider(tenant_id, instance.id)
+
+ assert result
+ expected_tmp_calls = [
+ call(f"db-tmp-scan-{str(aps1.id).lower()}"),
+ call(f"db-tmp-scan-{str(aps2.id).lower()}"),
+ ]
+ mock_drop_database.assert_has_calls(expected_tmp_calls, any_order=True)
+
+ def test_delete_provider_continues_when_temp_db_drop_fails(
+ self, providers_fixture, create_attack_paths_scan
+ ):
+ instance = providers_fixture[0]
+ tenant_id = str(instance.tenant_id)
+
+ create_attack_paths_scan(instance)
+
+ with (
+ patch(
+ "tasks.jobs.deletion.graph_database.drop_subgraph",
+ ),
+ patch(
+ "tasks.jobs.deletion.graph_database.drop_database",
+ side_effect=graph_database.GraphDatabaseQueryException(
+ "Neo4j unreachable"
+ ),
+ ),
+ ):
+ result = delete_provider(tenant_id, instance.id)
+
+ assert result
+ assert not Provider.all_objects.filter(pk=instance.id).exists()
@pytest.mark.django_db
@@ -142,3 +190,56 @@ class TestDeleteTenant:
mock_get_database_name.assert_called_once_with(tenant.id)
mock_drop_subgraph.assert_not_called()
mock_drop_database.assert_called_once_with("tenant-db")
+
+ def test_delete_tenant_includes_soft_deleted_providers(self, tenants_fixture):
+ tenant = tenants_fixture[0]
+ provider = Provider.objects.create(
+ provider="aws",
+ uid="999999999999",
+ alias="soft_deleted_provider",
+ tenant_id=tenant.id,
+ )
+ # Soft-delete the provider so ActiveProviderManager would skip it
+ Provider.all_objects.filter(pk=provider.id).update(is_deleted=True)
+
+ with (
+ patch(
+ "tasks.jobs.deletion.graph_database.get_database_name",
+ return_value="tenant-db",
+ ),
+ patch(
+ "tasks.jobs.deletion.graph_database.drop_subgraph"
+ ) as mock_drop_subgraph,
+ patch("tasks.jobs.deletion.graph_database.drop_database"),
+ ):
+ delete_tenant(tenant.id)
+
+ mock_drop_subgraph.assert_any_call("tenant-db", str(provider.id))
+
+ def test_delete_tenant_handles_concurrently_deleted_provider(self, tenants_fixture):
+ tenant = tenants_fixture[0]
+ Provider.objects.create(
+ provider="aws",
+ uid="111111111111",
+ alias="vanishing_provider",
+ tenant_id=tenant.id,
+ )
+
+ def drop_subgraph_side_effect(_db_name, provider_id):
+ # Simulate concurrent deletion by another process
+ Provider.all_objects.filter(pk=provider_id).delete()
+
+ with (
+ patch(
+ "tasks.jobs.deletion.graph_database.get_database_name",
+ return_value="tenant-db",
+ ),
+ patch(
+ "tasks.jobs.deletion.graph_database.drop_subgraph",
+ side_effect=drop_subgraph_side_effect,
+ ),
+ patch("tasks.jobs.deletion.graph_database.drop_database"),
+ ):
+ deletion_summary = delete_tenant(tenant.id)
+
+ assert deletion_summary is not None
diff --git a/api/src/backend/tasks/tests/test_reports_csa.py b/api/src/backend/tasks/tests/test_reports_csa.py
new file mode 100644
index 0000000000..602b9bb28e
--- /dev/null
+++ b/api/src/backend/tasks/tests/test_reports_csa.py
@@ -0,0 +1,1085 @@
+import io
+from unittest.mock import Mock
+
+import pytest
+from reportlab.platypus import PageBreak, Paragraph, Table
+from tasks.jobs.reports import FRAMEWORK_REGISTRY, ComplianceData, RequirementData
+from tasks.jobs.reports.csa import CSAReportGenerator
+
+
+# Use string status values directly to avoid Django DB initialization
+# These match api.models.StatusChoices values
+class StatusChoices:
+ """Mock StatusChoices to avoid Django DB initialization."""
+
+ PASS = "PASS"
+ FAIL = "FAIL"
+ MANUAL = "MANUAL"
+
+
+# =============================================================================
+# Fixtures
+# =============================================================================
+
+
+@pytest.fixture
+def csa_generator():
+ """Create a CSAReportGenerator instance for testing."""
+ config = FRAMEWORK_REGISTRY["csa_ccm"]
+ return CSAReportGenerator(config)
+
+
+@pytest.fixture
+def mock_csa_requirement_attribute_iam():
+ """Create a mock CSA CCM requirement attribute for Identity & Access Management."""
+ mock = Mock()
+ mock.Section = "Identity & Access Management"
+ mock.CCMLite = "Yes"
+ mock.IaaS = "Yes"
+ mock.PaaS = "Yes"
+ mock.SaaS = "Yes"
+ mock.ScopeApplicability = [
+ {"ReferenceId": "ISO 27001", "Identifiers": ["A.9.1.1", "A.9.2.3"]},
+ {"ReferenceId": "NIST 800-53", "Identifiers": ["AC-2", "AC-3", "AC-6"]},
+ ]
+ return mock
+
+
+@pytest.fixture
+def mock_csa_requirement_attribute_logging():
+ """Create a mock CSA CCM requirement attribute for Logging and Monitoring."""
+ mock = Mock()
+ mock.Section = "Logging and Monitoring"
+ mock.CCMLite = "Yes"
+ mock.IaaS = "Yes"
+ mock.PaaS = "No"
+ mock.SaaS = "No"
+ mock.ScopeApplicability = [
+ {"ReferenceId": "ISO 27001", "Identifiers": ["A.12.4.1"]},
+ ]
+ return mock
+
+
+@pytest.fixture
+def mock_csa_requirement_attribute_crypto():
+ """Create a mock CSA CCM requirement attribute for Cryptography."""
+ mock = Mock()
+ mock.Section = "Cryptography, Encryption & Key Management"
+ mock.CCMLite = "No"
+ mock.IaaS = "Yes"
+ mock.PaaS = "Yes"
+ mock.SaaS = "No"
+ mock.ScopeApplicability = []
+ return mock
+
+
+@pytest.fixture
+def basic_csa_compliance_data():
+ """Create basic ComplianceData for CSA CCM testing."""
+ return ComplianceData(
+ tenant_id="tenant-123",
+ scan_id="scan-456",
+ provider_id="provider-789",
+ compliance_id="csa_ccm_4.0_aws",
+ framework="CSA-CCM",
+ name="CSA Cloud Controls Matrix v4.0",
+ version="4.0",
+ description="Cloud Security Alliance Cloud Controls Matrix",
+ )
+
+
+# =============================================================================
+# Generator Initialization Tests
+# =============================================================================
+
+
+class TestCSAGeneratorInitialization:
+ """Test suite for CSA generator initialization."""
+
+ def test_generator_creation(self, csa_generator):
+ """Test that CSA generator is created correctly."""
+ assert csa_generator is not None
+ assert csa_generator.config.name == "csa_ccm"
+ assert csa_generator.config.language == "en"
+
+ def test_generator_no_niveles(self, csa_generator):
+ """Test that CSA config does not use niveles."""
+ assert csa_generator.config.has_niveles is False
+
+ def test_generator_no_dimensions(self, csa_generator):
+ """Test that CSA config does not use dimensions."""
+ assert csa_generator.config.has_dimensions is False
+
+ def test_generator_no_risk_levels(self, csa_generator):
+ """Test that CSA config does not use risk levels."""
+ assert csa_generator.config.has_risk_levels is False
+
+ def test_generator_no_weight(self, csa_generator):
+ """Test that CSA config does not use weight."""
+ assert csa_generator.config.has_weight is False
+
+
+# =============================================================================
+# Cover Page Tests
+# =============================================================================
+
+
+class TestCSACoverPage:
+ """Test suite for CSA cover page generation."""
+
+ def test_cover_page_has_logo(self, csa_generator, basic_csa_compliance_data):
+ """Test that cover page contains the Prowler logo."""
+ basic_csa_compliance_data.requirements = []
+ basic_csa_compliance_data.attributes_by_requirement_id = {}
+
+ elements = csa_generator.create_cover_page(basic_csa_compliance_data)
+
+ assert len(elements) > 0
+
+ def test_cover_page_has_title(self, csa_generator, basic_csa_compliance_data):
+ """Test that cover page contains the CSA CCM title."""
+ basic_csa_compliance_data.requirements = []
+ basic_csa_compliance_data.attributes_by_requirement_id = {}
+
+ elements = csa_generator.create_cover_page(basic_csa_compliance_data)
+
+ paragraphs = [e for e in elements if isinstance(e, Paragraph)]
+ content = " ".join(str(p.text) for p in paragraphs)
+ assert "CSA" in content or "CCM" in content or "Cloud Controls" in content
+
+ def test_cover_page_has_metadata_table(
+ self, csa_generator, basic_csa_compliance_data
+ ):
+ """Test that cover page contains metadata table."""
+ basic_csa_compliance_data.requirements = []
+ basic_csa_compliance_data.attributes_by_requirement_id = {}
+
+ elements = csa_generator.create_cover_page(basic_csa_compliance_data)
+
+ tables = [e for e in elements if isinstance(e, Table)]
+ assert len(tables) >= 1
+
+
+# =============================================================================
+# Executive Summary Tests
+# =============================================================================
+
+
+class TestCSAExecutiveSummary:
+ """Test suite for CSA executive summary generation."""
+
+ def test_executive_summary_has_english_title(
+ self, csa_generator, basic_csa_compliance_data
+ ):
+ """Test that executive summary has English title."""
+ basic_csa_compliance_data.requirements = []
+ basic_csa_compliance_data.attributes_by_requirement_id = {}
+
+ elements = csa_generator.create_executive_summary(basic_csa_compliance_data)
+
+ paragraphs = [e for e in elements if isinstance(e, Paragraph)]
+ content = " ".join(str(p.text) for p in paragraphs)
+ assert "Executive Summary" in content
+
+ def test_executive_summary_calculates_compliance(
+ self,
+ csa_generator,
+ basic_csa_compliance_data,
+ mock_csa_requirement_attribute_iam,
+ ):
+ """Test that executive summary calculates compliance percentage."""
+ basic_csa_compliance_data.requirements = [
+ RequirementData(
+ id="REQ-001",
+ description="Passed requirement",
+ status=StatusChoices.PASS,
+ passed_findings=10,
+ failed_findings=0,
+ total_findings=10,
+ ),
+ RequirementData(
+ id="REQ-002",
+ description="Failed requirement",
+ status=StatusChoices.FAIL,
+ passed_findings=0,
+ failed_findings=10,
+ total_findings=10,
+ ),
+ ]
+ basic_csa_compliance_data.attributes_by_requirement_id = {
+ "REQ-001": {
+ "attributes": {"req_attributes": [mock_csa_requirement_attribute_iam]}
+ },
+ "REQ-002": {
+ "attributes": {"req_attributes": [mock_csa_requirement_attribute_iam]}
+ },
+ }
+
+ elements = csa_generator.create_executive_summary(basic_csa_compliance_data)
+
+ # Should contain tables with metrics
+ tables = [e for e in elements if isinstance(e, Table)]
+ assert len(tables) >= 1
+
+ def test_executive_summary_shows_all_statuses(
+ self,
+ csa_generator,
+ basic_csa_compliance_data,
+ mock_csa_requirement_attribute_iam,
+ ):
+ """Test that executive summary shows passed, failed, and manual counts."""
+ basic_csa_compliance_data.requirements = [
+ RequirementData(
+ id="REQ-001",
+ description="Passed",
+ status=StatusChoices.PASS,
+ passed_findings=10,
+ failed_findings=0,
+ total_findings=10,
+ ),
+ RequirementData(
+ id="REQ-002",
+ description="Failed",
+ status=StatusChoices.FAIL,
+ passed_findings=0,
+ failed_findings=10,
+ total_findings=10,
+ ),
+ RequirementData(
+ id="REQ-003",
+ description="Manual",
+ status=StatusChoices.MANUAL,
+ passed_findings=0,
+ failed_findings=0,
+ total_findings=0,
+ ),
+ ]
+ basic_csa_compliance_data.attributes_by_requirement_id = {
+ "REQ-001": {
+ "attributes": {"req_attributes": [mock_csa_requirement_attribute_iam]}
+ },
+ "REQ-002": {
+ "attributes": {"req_attributes": [mock_csa_requirement_attribute_iam]}
+ },
+ "REQ-003": {
+ "attributes": {"req_attributes": [mock_csa_requirement_attribute_iam]}
+ },
+ }
+
+ elements = csa_generator.create_executive_summary(basic_csa_compliance_data)
+
+ # Should have a summary table with all statuses
+ assert len(elements) > 0
+
+ def test_executive_summary_excludes_manual_from_percentage(
+ self,
+ csa_generator,
+ basic_csa_compliance_data,
+ mock_csa_requirement_attribute_iam,
+ ):
+ """Test that manual requirements are excluded from compliance percentage."""
+ basic_csa_compliance_data.requirements = [
+ RequirementData(
+ id="REQ-001",
+ description="Passed",
+ status=StatusChoices.PASS,
+ passed_findings=10,
+ failed_findings=0,
+ total_findings=10,
+ ),
+ RequirementData(
+ id="REQ-002",
+ description="Manual",
+ status=StatusChoices.MANUAL,
+ passed_findings=0,
+ failed_findings=0,
+ total_findings=0,
+ ),
+ ]
+ basic_csa_compliance_data.attributes_by_requirement_id = {
+ "REQ-001": {
+ "attributes": {"req_attributes": [mock_csa_requirement_attribute_iam]}
+ },
+ "REQ-002": {
+ "attributes": {"req_attributes": [mock_csa_requirement_attribute_iam]}
+ },
+ }
+
+ elements = csa_generator.create_executive_summary(basic_csa_compliance_data)
+
+ # Should calculate 100% (only 1 evaluated requirement that passed)
+ assert len(elements) > 0
+
+
+# =============================================================================
+# Charts Section Tests
+# =============================================================================
+
+
+class TestCSAChartsSection:
+ """Test suite for CSA charts section generation."""
+
+ def test_charts_section_has_section_chart_title(
+ self, csa_generator, basic_csa_compliance_data
+ ):
+ """Test that charts section has section compliance title."""
+ basic_csa_compliance_data.requirements = []
+ basic_csa_compliance_data.attributes_by_requirement_id = {}
+
+ elements = csa_generator.create_charts_section(basic_csa_compliance_data)
+
+ paragraphs = [e for e in elements if isinstance(e, Paragraph)]
+ content = " ".join(str(p.text) for p in paragraphs)
+ assert "Section" in content or "Compliance" in content
+
+ def test_charts_section_has_page_break(
+ self, csa_generator, basic_csa_compliance_data
+ ):
+ """Test that charts section has page breaks."""
+ basic_csa_compliance_data.requirements = []
+ basic_csa_compliance_data.attributes_by_requirement_id = {}
+
+ elements = csa_generator.create_charts_section(basic_csa_compliance_data)
+
+ page_breaks = [e for e in elements if isinstance(e, PageBreak)]
+ assert len(page_breaks) >= 1
+
+ def test_charts_section_has_section_breakdown(
+ self,
+ csa_generator,
+ basic_csa_compliance_data,
+ mock_csa_requirement_attribute_iam,
+ ):
+ """Test that charts section includes section breakdown table."""
+ basic_csa_compliance_data.requirements = [
+ RequirementData(
+ id="REQ-001",
+ description="Test requirement",
+ status=StatusChoices.PASS,
+ passed_findings=10,
+ failed_findings=0,
+ total_findings=10,
+ ),
+ ]
+ basic_csa_compliance_data.attributes_by_requirement_id = {
+ "REQ-001": {
+ "attributes": {"req_attributes": [mock_csa_requirement_attribute_iam]}
+ },
+ }
+
+ elements = csa_generator.create_charts_section(basic_csa_compliance_data)
+
+ paragraphs = [e for e in elements if isinstance(e, Paragraph)]
+ content = " ".join(str(p.text) for p in paragraphs)
+ assert "Section" in content or "Breakdown" in content
+
+
+# =============================================================================
+# Section Chart Tests
+# =============================================================================
+
+
+class TestCSASectionChart:
+ """Test suite for CSA section compliance chart."""
+
+ def test_section_chart_creation(
+ self,
+ csa_generator,
+ basic_csa_compliance_data,
+ mock_csa_requirement_attribute_iam,
+ ):
+ """Test that section chart is created successfully."""
+ basic_csa_compliance_data.requirements = [
+ RequirementData(
+ id="REQ-001",
+ description="Test requirement",
+ status=StatusChoices.PASS,
+ passed_findings=10,
+ failed_findings=0,
+ total_findings=10,
+ ),
+ ]
+ basic_csa_compliance_data.attributes_by_requirement_id = {
+ "REQ-001": {
+ "attributes": {"req_attributes": [mock_csa_requirement_attribute_iam]}
+ },
+ }
+
+ chart_buffer = csa_generator._create_section_chart(basic_csa_compliance_data)
+
+ assert isinstance(chart_buffer, io.BytesIO)
+ assert chart_buffer.getvalue() # Not empty
+
+ def test_section_chart_excludes_manual(
+ self,
+ csa_generator,
+ basic_csa_compliance_data,
+ mock_csa_requirement_attribute_iam,
+ ):
+ """Test that manual requirements are excluded from section chart."""
+ basic_csa_compliance_data.requirements = [
+ RequirementData(
+ id="REQ-001",
+ description="Auto requirement",
+ status=StatusChoices.PASS,
+ passed_findings=10,
+ failed_findings=0,
+ total_findings=10,
+ ),
+ RequirementData(
+ id="REQ-002",
+ description="Manual requirement",
+ status=StatusChoices.MANUAL,
+ passed_findings=0,
+ failed_findings=0,
+ total_findings=0,
+ ),
+ ]
+ basic_csa_compliance_data.attributes_by_requirement_id = {
+ "REQ-001": {
+ "attributes": {"req_attributes": [mock_csa_requirement_attribute_iam]}
+ },
+ "REQ-002": {
+ "attributes": {"req_attributes": [mock_csa_requirement_attribute_iam]}
+ },
+ }
+
+ # Should not raise any errors
+ chart_buffer = csa_generator._create_section_chart(basic_csa_compliance_data)
+ assert isinstance(chart_buffer, io.BytesIO)
+
+ def test_section_chart_multiple_sections(
+ self,
+ csa_generator,
+ basic_csa_compliance_data,
+ mock_csa_requirement_attribute_iam,
+ mock_csa_requirement_attribute_logging,
+ mock_csa_requirement_attribute_crypto,
+ ):
+ """Test section chart with multiple sections."""
+ basic_csa_compliance_data.requirements = [
+ RequirementData(
+ id="REQ-001",
+ description="IAM requirement",
+ status=StatusChoices.PASS,
+ passed_findings=10,
+ failed_findings=0,
+ total_findings=10,
+ ),
+ RequirementData(
+ id="REQ-002",
+ description="Logging requirement",
+ status=StatusChoices.FAIL,
+ passed_findings=0,
+ failed_findings=10,
+ total_findings=10,
+ ),
+ RequirementData(
+ id="REQ-003",
+ description="Crypto requirement",
+ status=StatusChoices.PASS,
+ passed_findings=5,
+ failed_findings=0,
+ total_findings=5,
+ ),
+ ]
+ basic_csa_compliance_data.attributes_by_requirement_id = {
+ "REQ-001": {
+ "attributes": {"req_attributes": [mock_csa_requirement_attribute_iam]}
+ },
+ "REQ-002": {
+ "attributes": {
+ "req_attributes": [mock_csa_requirement_attribute_logging]
+ }
+ },
+ "REQ-003": {
+ "attributes": {
+ "req_attributes": [mock_csa_requirement_attribute_crypto]
+ }
+ },
+ }
+
+ chart_buffer = csa_generator._create_section_chart(basic_csa_compliance_data)
+ assert isinstance(chart_buffer, io.BytesIO)
+
+
+# =============================================================================
+# Section Table Tests
+# =============================================================================
+
+
+class TestCSASectionTable:
+ """Test suite for CSA section breakdown table."""
+
+ def test_section_table_creation(
+ self,
+ csa_generator,
+ basic_csa_compliance_data,
+ mock_csa_requirement_attribute_iam,
+ ):
+ """Test that section table is created successfully."""
+ basic_csa_compliance_data.requirements = [
+ RequirementData(
+ id="REQ-001",
+ description="Test requirement",
+ status=StatusChoices.PASS,
+ passed_findings=10,
+ failed_findings=0,
+ total_findings=10,
+ ),
+ ]
+ basic_csa_compliance_data.attributes_by_requirement_id = {
+ "REQ-001": {
+ "attributes": {"req_attributes": [mock_csa_requirement_attribute_iam]}
+ },
+ }
+
+ table = csa_generator._create_section_table(basic_csa_compliance_data)
+
+ assert isinstance(table, Table)
+
+ def test_section_table_counts_statuses(
+ self,
+ csa_generator,
+ basic_csa_compliance_data,
+ mock_csa_requirement_attribute_iam,
+ ):
+ """Test that section table counts passed, failed, and manual."""
+ basic_csa_compliance_data.requirements = [
+ RequirementData(
+ id="REQ-001",
+ description="Passed",
+ status=StatusChoices.PASS,
+ passed_findings=10,
+ failed_findings=0,
+ total_findings=10,
+ ),
+ RequirementData(
+ id="REQ-002",
+ description="Failed",
+ status=StatusChoices.FAIL,
+ passed_findings=0,
+ failed_findings=10,
+ total_findings=10,
+ ),
+ RequirementData(
+ id="REQ-003",
+ description="Manual",
+ status=StatusChoices.MANUAL,
+ passed_findings=0,
+ failed_findings=0,
+ total_findings=0,
+ ),
+ ]
+ basic_csa_compliance_data.attributes_by_requirement_id = {
+ "REQ-001": {
+ "attributes": {"req_attributes": [mock_csa_requirement_attribute_iam]}
+ },
+ "REQ-002": {
+ "attributes": {"req_attributes": [mock_csa_requirement_attribute_iam]}
+ },
+ "REQ-003": {
+ "attributes": {"req_attributes": [mock_csa_requirement_attribute_iam]}
+ },
+ }
+
+ table = csa_generator._create_section_table(basic_csa_compliance_data)
+ assert isinstance(table, Table)
+
+
+# =============================================================================
+# Requirements Index Tests
+# =============================================================================
+
+
+class TestCSARequirementsIndex:
+ """Test suite for CSA requirements index generation."""
+
+ def test_requirements_index_has_title(
+ self, csa_generator, basic_csa_compliance_data
+ ):
+ """Test that requirements index has English title."""
+ basic_csa_compliance_data.requirements = []
+ basic_csa_compliance_data.attributes_by_requirement_id = {}
+
+ elements = csa_generator.create_requirements_index(basic_csa_compliance_data)
+
+ paragraphs = [e for e in elements if isinstance(e, Paragraph)]
+ content = " ".join(str(p.text) for p in paragraphs)
+ assert "Requirements Index" in content
+
+ def test_requirements_index_organized_by_section(
+ self,
+ csa_generator,
+ basic_csa_compliance_data,
+ mock_csa_requirement_attribute_iam,
+ mock_csa_requirement_attribute_logging,
+ ):
+ """Test that requirements index is organized by section."""
+ basic_csa_compliance_data.requirements = [
+ RequirementData(
+ id="REQ-001",
+ description="IAM requirement",
+ status=StatusChoices.PASS,
+ passed_findings=10,
+ failed_findings=0,
+ total_findings=10,
+ ),
+ RequirementData(
+ id="REQ-002",
+ description="Logging requirement",
+ status=StatusChoices.PASS,
+ passed_findings=5,
+ failed_findings=0,
+ total_findings=5,
+ ),
+ ]
+ basic_csa_compliance_data.attributes_by_requirement_id = {
+ "REQ-001": {
+ "attributes": {"req_attributes": [mock_csa_requirement_attribute_iam]}
+ },
+ "REQ-002": {
+ "attributes": {
+ "req_attributes": [mock_csa_requirement_attribute_logging]
+ }
+ },
+ }
+
+ elements = csa_generator.create_requirements_index(basic_csa_compliance_data)
+
+ paragraphs = [e for e in elements if isinstance(e, Paragraph)]
+ content = " ".join(str(p.text) for p in paragraphs)
+ # Should have section headers
+ assert "Identity" in content or "Logging" in content or "Access" in content
+
+ def test_requirements_index_shows_status_indicators(
+ self,
+ csa_generator,
+ basic_csa_compliance_data,
+ mock_csa_requirement_attribute_iam,
+ ):
+ """Test that requirements index shows pass/fail/manual indicators."""
+ basic_csa_compliance_data.requirements = [
+ RequirementData(
+ id="REQ-001",
+ description="Passed requirement",
+ status=StatusChoices.PASS,
+ passed_findings=10,
+ failed_findings=0,
+ total_findings=10,
+ ),
+ RequirementData(
+ id="REQ-002",
+ description="Failed requirement",
+ status=StatusChoices.FAIL,
+ passed_findings=0,
+ failed_findings=10,
+ total_findings=10,
+ ),
+ RequirementData(
+ id="REQ-003",
+ description="Manual requirement",
+ status=StatusChoices.MANUAL,
+ passed_findings=0,
+ failed_findings=0,
+ total_findings=0,
+ ),
+ ]
+ basic_csa_compliance_data.attributes_by_requirement_id = {
+ "REQ-001": {
+ "attributes": {"req_attributes": [mock_csa_requirement_attribute_iam]}
+ },
+ "REQ-002": {
+ "attributes": {"req_attributes": [mock_csa_requirement_attribute_iam]}
+ },
+ "REQ-003": {
+ "attributes": {"req_attributes": [mock_csa_requirement_attribute_iam]}
+ },
+ }
+
+ elements = csa_generator.create_requirements_index(basic_csa_compliance_data)
+
+ paragraphs = [e for e in elements if isinstance(e, Paragraph)]
+ content = " ".join(str(p.text) for p in paragraphs)
+ # Should have status indicators
+ assert "\u2713" in content or "\u2717" in content or "\u2299" in content
+
+ def test_requirements_index_truncates_long_descriptions(
+ self, csa_generator, basic_csa_compliance_data
+ ):
+ """Test that long descriptions are truncated."""
+ mock_attr = Mock()
+ mock_attr.Section = "Identity & Access Management"
+ mock_attr.CCMLite = "Yes"
+ mock_attr.IaaS = "Yes"
+ mock_attr.PaaS = "Yes"
+ mock_attr.SaaS = "Yes"
+ mock_attr.ScopeApplicability = []
+
+ basic_csa_compliance_data.requirements = [
+ RequirementData(
+ id="REQ-001",
+ description="A" * 100,
+ status=StatusChoices.PASS,
+ passed_findings=10,
+ failed_findings=0,
+ total_findings=10,
+ ),
+ ]
+ basic_csa_compliance_data.attributes_by_requirement_id = {
+ "REQ-001": {"attributes": {"req_attributes": [mock_attr]}},
+ }
+
+ # Should not raise errors
+ elements = csa_generator.create_requirements_index(basic_csa_compliance_data)
+ assert len(elements) > 0
+
+
+# =============================================================================
+# Requirement Attributes Tests
+# =============================================================================
+
+
+class TestCSARequirementAttributes:
+ """Test suite for CSA requirement attributes display."""
+
+ def test_format_attributes_applicability_line(
+ self, csa_generator, mock_csa_requirement_attribute_iam
+ ):
+ """Test that applicability attributes (CCMLite, IaaS, PaaS, SaaS) are rendered."""
+ elements = csa_generator._format_requirement_attributes(
+ mock_csa_requirement_attribute_iam
+ )
+
+ paragraphs = [e for e in elements if isinstance(e, Paragraph)]
+ content = " ".join(str(p.text) for p in paragraphs)
+ assert "CCMLite: Yes" in content
+ assert "IaaS: Yes" in content
+ assert "PaaS: Yes" in content
+ assert "SaaS: Yes" in content
+
+ def test_format_attributes_partial_applicability(
+ self, csa_generator, mock_csa_requirement_attribute_logging
+ ):
+ """Test attributes when some applicability fields are 'No'."""
+ elements = csa_generator._format_requirement_attributes(
+ mock_csa_requirement_attribute_logging
+ )
+
+ paragraphs = [e for e in elements if isinstance(e, Paragraph)]
+ content = " ".join(str(p.text) for p in paragraphs)
+ assert "IaaS: Yes" in content
+ assert "PaaS: No" in content
+
+ def test_format_attributes_scope_applicability_refs(
+ self, csa_generator, mock_csa_requirement_attribute_iam
+ ):
+ """Test that ScopeApplicability references are displayed."""
+ elements = csa_generator._format_requirement_attributes(
+ mock_csa_requirement_attribute_iam
+ )
+
+ paragraphs = [e for e in elements if isinstance(e, Paragraph)]
+ content = " ".join(str(p.text) for p in paragraphs)
+ assert "ISO 27001" in content
+ assert "NIST 800-53" in content
+
+ def test_format_attributes_empty_scope(
+ self, csa_generator, mock_csa_requirement_attribute_crypto
+ ):
+ """Test that empty ScopeApplicability produces no reference line."""
+ elements = csa_generator._format_requirement_attributes(
+ mock_csa_requirement_attribute_crypto
+ )
+
+ # Should have applicability line but no scope reference line
+ paragraphs = [e for e in elements if isinstance(e, Paragraph)]
+ assert len(paragraphs) == 1 # Only the applicability line
+
+ def test_format_attributes_no_applicability(self, csa_generator):
+ """Test attributes when all applicability fields are empty."""
+ mock = Mock()
+ mock.CCMLite = ""
+ mock.IaaS = ""
+ mock.PaaS = ""
+ mock.SaaS = ""
+ mock.ScopeApplicability = []
+
+ elements = csa_generator._format_requirement_attributes(mock)
+
+ assert len(elements) == 0
+
+ def test_format_attributes_truncates_long_identifiers(self, csa_generator):
+ """Test that ScopeApplicability with many identifiers is truncated."""
+ mock = Mock()
+ mock.CCMLite = "Yes"
+ mock.IaaS = "Yes"
+ mock.PaaS = "Yes"
+ mock.SaaS = "Yes"
+ mock.ScopeApplicability = [
+ {
+ "ReferenceId": "NIST 800-53",
+ "Identifiers": ["AC-1", "AC-2", "AC-3", "AC-4", "AC-5", "AC-6"],
+ },
+ ]
+
+ elements = csa_generator._format_requirement_attributes(mock)
+
+ paragraphs = [e for e in elements if isinstance(e, Paragraph)]
+ content = " ".join(str(p.text) for p in paragraphs)
+ # Should show first 4 and ellipsis
+ assert "AC-1" in content
+ assert "AC-4" in content
+ assert "..." in content
+
+ def test_attr_style_returns_paragraph_style(self, csa_generator):
+ """Test that _attr_style returns a valid ParagraphStyle."""
+ from reportlab.lib.styles import ParagraphStyle
+
+ style = csa_generator._attr_style()
+ assert isinstance(style, ParagraphStyle)
+ assert style.fontSize == 10
+ assert style.leftIndent == 30
+
+ def test_render_requirement_detail_extras(
+ self,
+ csa_generator,
+ basic_csa_compliance_data,
+ mock_csa_requirement_attribute_iam,
+ ):
+ """Test that detail extras hook renders CSA attributes."""
+ req = RequirementData(
+ id="REQ-001",
+ description="IAM requirement",
+ status=StatusChoices.PASS,
+ passed_findings=10,
+ failed_findings=0,
+ total_findings=10,
+ )
+ basic_csa_compliance_data.attributes_by_requirement_id = {
+ "REQ-001": {
+ "attributes": {"req_attributes": [mock_csa_requirement_attribute_iam]}
+ },
+ }
+
+ elements = csa_generator._render_requirement_detail_extras(
+ req, basic_csa_compliance_data
+ )
+
+ paragraphs = [e for e in elements if isinstance(e, Paragraph)]
+ content = " ".join(str(p.text) for p in paragraphs)
+ assert "CCMLite" in content
+ assert "ISO 27001" in content
+
+ def test_render_requirement_detail_extras_no_metadata(
+ self,
+ csa_generator,
+ basic_csa_compliance_data,
+ ):
+ """Test that detail extras returns empty when no metadata found."""
+ req = RequirementData(
+ id="REQ-UNKNOWN",
+ description="No metadata",
+ status=StatusChoices.PASS,
+ passed_findings=0,
+ failed_findings=0,
+ total_findings=0,
+ )
+ basic_csa_compliance_data.attributes_by_requirement_id = {}
+
+ elements = csa_generator._render_requirement_detail_extras(
+ req, basic_csa_compliance_data
+ )
+
+ assert elements == []
+
+
+# =============================================================================
+# Empty Data Tests
+# =============================================================================
+
+
+class TestCSAEmptyData:
+ """Test suite for CSA with empty or minimal data."""
+
+ def test_executive_summary_empty_requirements(
+ self, csa_generator, basic_csa_compliance_data
+ ):
+ """Test executive summary with no requirements."""
+ basic_csa_compliance_data.requirements = []
+ basic_csa_compliance_data.attributes_by_requirement_id = {}
+
+ elements = csa_generator.create_executive_summary(basic_csa_compliance_data)
+
+ assert len(elements) > 0
+
+ def test_charts_section_empty_requirements(
+ self, csa_generator, basic_csa_compliance_data
+ ):
+ """Test charts section with no requirements."""
+ basic_csa_compliance_data.requirements = []
+ basic_csa_compliance_data.attributes_by_requirement_id = {}
+
+ elements = csa_generator.create_charts_section(basic_csa_compliance_data)
+
+ assert len(elements) > 0
+
+ def test_requirements_index_empty(self, csa_generator, basic_csa_compliance_data):
+ """Test requirements index with no requirements."""
+ basic_csa_compliance_data.requirements = []
+ basic_csa_compliance_data.attributes_by_requirement_id = {}
+
+ elements = csa_generator.create_requirements_index(basic_csa_compliance_data)
+
+ # Should at least have the title
+ assert len(elements) >= 1
+
+
+# =============================================================================
+# All Pass / All Fail Tests
+# =============================================================================
+
+
+class TestCSAEdgeCases:
+ """Test suite for CSA edge cases."""
+
+ def test_all_requirements_pass(
+ self,
+ csa_generator,
+ basic_csa_compliance_data,
+ mock_csa_requirement_attribute_iam,
+ ):
+ """Test with all requirements passing."""
+ basic_csa_compliance_data.requirements = [
+ RequirementData(
+ id=f"REQ-{i:03d}",
+ description=f"Passing requirement {i}",
+ status=StatusChoices.PASS,
+ passed_findings=10,
+ failed_findings=0,
+ total_findings=10,
+ )
+ for i in range(1, 6)
+ ]
+ basic_csa_compliance_data.attributes_by_requirement_id = {
+ f"REQ-{i:03d}": {
+ "attributes": {"req_attributes": [mock_csa_requirement_attribute_iam]}
+ }
+ for i in range(1, 6)
+ }
+
+ elements = csa_generator.create_executive_summary(basic_csa_compliance_data)
+ assert len(elements) > 0
+
+ def test_all_requirements_fail(
+ self,
+ csa_generator,
+ basic_csa_compliance_data,
+ mock_csa_requirement_attribute_iam,
+ ):
+ """Test with all requirements failing."""
+ basic_csa_compliance_data.requirements = [
+ RequirementData(
+ id=f"REQ-{i:03d}",
+ description=f"Failing requirement {i}",
+ status=StatusChoices.FAIL,
+ passed_findings=0,
+ failed_findings=10,
+ total_findings=10,
+ )
+ for i in range(1, 6)
+ ]
+ basic_csa_compliance_data.attributes_by_requirement_id = {
+ f"REQ-{i:03d}": {
+ "attributes": {"req_attributes": [mock_csa_requirement_attribute_iam]}
+ }
+ for i in range(1, 6)
+ }
+
+ elements = csa_generator.create_executive_summary(basic_csa_compliance_data)
+ assert len(elements) > 0
+
+ def test_all_requirements_manual(
+ self,
+ csa_generator,
+ basic_csa_compliance_data,
+ mock_csa_requirement_attribute_iam,
+ ):
+ """Test with all requirements being manual."""
+ basic_csa_compliance_data.requirements = [
+ RequirementData(
+ id=f"REQ-{i:03d}",
+ description=f"Manual requirement {i}",
+ status=StatusChoices.MANUAL,
+ passed_findings=0,
+ failed_findings=0,
+ total_findings=0,
+ )
+ for i in range(1, 6)
+ ]
+ basic_csa_compliance_data.attributes_by_requirement_id = {
+ f"REQ-{i:03d}": {
+ "attributes": {"req_attributes": [mock_csa_requirement_attribute_iam]}
+ }
+ for i in range(1, 6)
+ }
+
+ # Should handle gracefully - compliance should be 100% when no evaluated
+ elements = csa_generator.create_executive_summary(basic_csa_compliance_data)
+ assert len(elements) > 0
+
+
+# =============================================================================
+# Integration Tests
+# =============================================================================
+
+
+class TestCSAIntegration:
+ """Integration tests for CSA report generation."""
+
+ def test_full_report_generation_flow(
+ self,
+ csa_generator,
+ basic_csa_compliance_data,
+ mock_csa_requirement_attribute_iam,
+ mock_csa_requirement_attribute_logging,
+ ):
+ """Test the complete report generation flow."""
+ basic_csa_compliance_data.requirements = [
+ RequirementData(
+ id="REQ-001",
+ description="IAM passed",
+ status=StatusChoices.PASS,
+ passed_findings=10,
+ failed_findings=0,
+ total_findings=10,
+ ),
+ RequirementData(
+ id="REQ-002",
+ description="Logging failed",
+ status=StatusChoices.FAIL,
+ passed_findings=0,
+ failed_findings=5,
+ total_findings=5,
+ ),
+ ]
+ basic_csa_compliance_data.attributes_by_requirement_id = {
+ "REQ-001": {
+ "attributes": {"req_attributes": [mock_csa_requirement_attribute_iam]}
+ },
+ "REQ-002": {
+ "attributes": {
+ "req_attributes": [mock_csa_requirement_attribute_logging]
+ }
+ },
+ }
+
+ # Generate all sections
+ exec_summary = csa_generator.create_executive_summary(basic_csa_compliance_data)
+ charts = csa_generator.create_charts_section(basic_csa_compliance_data)
+ index = csa_generator.create_requirements_index(basic_csa_compliance_data)
+
+ # All sections should generate without errors
+ assert len(exec_summary) > 0
+ assert len(charts) > 0
+ assert len(index) > 0
diff --git a/contrib/k8s/helm/prowler-app/.helmignore b/contrib/k8s/helm/prowler-app/.helmignore
new file mode 100644
index 0000000000..7d250c5aa5
--- /dev/null
+++ b/contrib/k8s/helm/prowler-app/.helmignore
@@ -0,0 +1,24 @@
+# Patterns to ignore when building packages.
+# This supports shell glob matching, relative path matching, and
+# negation (prefixed with !). Only one pattern per line.
+examples
+.DS_Store
+# Common VCS dirs
+.git/
+.gitignore
+.bzr/
+.bzrignore
+.hg/
+.hgignore
+.svn/
+# Common backup files
+*.swp
+*.bak
+*.tmp
+*.orig
+*~
+# Various IDEs
+.project
+.idea/
+*.tmproj
+.vscode/
diff --git a/contrib/k8s/helm/prowler-app/Chart.lock b/contrib/k8s/helm/prowler-app/Chart.lock
new file mode 100644
index 0000000000..fe4af2f9e2
--- /dev/null
+++ b/contrib/k8s/helm/prowler-app/Chart.lock
@@ -0,0 +1,12 @@
+dependencies:
+- name: postgresql
+ repository: oci://registry-1.docker.io/bitnamicharts
+ version: 18.2.0
+- name: valkey
+ repository: https://valkey.io/valkey-helm/
+ version: 0.9.3
+- name: neo4j
+ repository: https://helm.neo4j.com/neo4j
+ version: 2025.12.1
+digest: sha256:da19233c6832727345fcdb314d683d30aa347d349f270023f3a67149bffb009b
+generated: "2026-01-26T12:00:06.798702+02:00"
diff --git a/contrib/k8s/helm/prowler-app/Chart.yaml b/contrib/k8s/helm/prowler-app/Chart.yaml
new file mode 100644
index 0000000000..5397d43569
--- /dev/null
+++ b/contrib/k8s/helm/prowler-app/Chart.yaml
@@ -0,0 +1,33 @@
+apiVersion: v2
+name: prowler
+description: Prowler is an Open Cloud Security tool for AWS, Azure, GCP and Kubernetes. It helps for continuous monitoring, security assessments and audits, incident response, compliance, hardening and forensics readiness.
+type: application
+version: 0.0.1
+appVersion: "5.17.0"
+home: https://prowler.com
+icon: https://cdn.prod.website-files.com/68c4ec3f9fb7b154fbcb6e36/68c5e0fea5d0059b9e05834b_Link.png
+keywords:
+ - security
+ - aws
+ - azure
+ - gcp
+ - kubernetes
+maintainers:
+ - name: Mihai
+ email: mihai.legat@gmail.com
+dependencies:
+ # https://artifacthub.io/packages/helm/bitnami/postgresql
+ - name: postgresql
+ version: 18.2.0
+ repository: oci://registry-1.docker.io/bitnamicharts
+ condition: postgresql.enabled
+ # https://valkey.io/valkey-helm/
+ - name: valkey
+ version: 0.9.3
+ repository: https://valkey.io/valkey-helm/
+ condition: valkey.enabled
+ # https://helm.neo4j.com/neo4j
+ - name: neo4j
+ version: 2025.12.1
+ repository: https://helm.neo4j.com/neo4j
+ condition: neo4j.enabled
diff --git a/contrib/k8s/helm/prowler-app/README.md b/contrib/k8s/helm/prowler-app/README.md
new file mode 100644
index 0000000000..544b5f39a7
--- /dev/null
+++ b/contrib/k8s/helm/prowler-app/README.md
@@ -0,0 +1,143 @@
+
+
+# Prowler App Helm Chart
+
+
+
+
+Prowler is an Open Cloud Security tool for AWS, Azure, GCP and Kubernetes. It helps for continuous monitoring, security assessments and audits, incident response, compliance, hardening and forensics readiness. Includes CIS, NIST 800, NIST CSF, CISA, FedRAMP, PCI-DSS, GDPR, HIPAA, FFIEC, SOC2, GXP, Well-Architected Security, ENS and more.
+
+## Architecture
+
+The Prowler App consists of three main components:
+
+- **Prowler UI**: A user-friendly web interface for running Prowler and viewing results, powered by Next.js.
+- **Prowler API**: The backend API that executes Prowler scans and stores the results, built with Django REST Framework.
+- **Prowler SDK**: A Python SDK that integrates with the Prowler CLI for advanced functionality.
+
+The app leverages the following supporting infrastructure:
+
+- **PostgreSQL**: Used for persistent storage of scan results.
+- **Celery Workers**: Facilitate asynchronous execution of Prowler scans.
+- **Valkey**: An in-memory database serving as a message broker for the Celery workers.
+- **Neo4j**: Graph Database
+- **Keda**: Kubernetes Event-driven Autoscaling (Keda) automatically scales the number of Celery worker pods based on the workload, ensuring efficient resource utilization and responsiveness.
+
+## Setup
+
+This guide walks you through installing Prowler App using Helm. For a minimal installation example, see the [minimal installation example](./examples/minimal-installation/).
+
+### Prerequisites
+
+- Kubernetes cluster (1.24+)
+- Helm 3.x installed
+- `kubectl` configured to access your cluster
+- Access to the Prowler Helm chart repository (or local chart)
+
+### Step 1: Create Required Secrets
+
+Before installing the Helm chart, you must create a Kubernetes Secret containing the required authentication keys and secrets.
+
+1. **Generate the required keys and secrets:**
+
+ ```bash
+ # Generate Django token signing key (private key)
+ openssl genrsa -out private.pem 2048
+
+ # Generate Django token verifying key (public key)
+ openssl rsa -in private.pem -pubout -out public.pem
+
+ # Generate Django secrets encryption key
+ openssl rand -base64 32
+
+ # Generate Auth secret
+ openssl rand -base64 32
+ ```
+
+2. **Create the secret file:**
+
+ Create a file named `secrets.yaml` with the following structure:
+
+ ```yaml
+ apiVersion: v1
+ kind: Secret
+ type: Opaque
+ metadata:
+ name: prowler-secret
+ stringData:
+ DJANGO_TOKEN_SIGNING_KEY: |
+ -----BEGIN PRIVATE KEY-----
+ [paste your private key here]
+ -----END PRIVATE KEY-----
+
+ DJANGO_TOKEN_VERIFYING_KEY: |
+ -----BEGIN PUBLIC KEY-----
+ [paste your public key here]
+ -----END PUBLIC KEY-----
+
+ DJANGO_SECRETS_ENCRYPTION_KEY: "[paste your encryption key here]"
+
+ AUTH_SECRET: "[paste your auth secret here]"
+
+ NEO4J_PASSWORD: "[prowler-password]"
+ NEO4J_AUTH: "neo4j/[prowler-password]"
+ ```
+
+ > **Note:** You can use the [example secrets file](./examples/minimal-installation/secrets.yaml) as a template, but **always replace the placeholder values with your own secure keys** before applying.
+
+3. **Apply the secret to your cluster:**
+
+ ```bash
+ kubectl apply -f secrets.yaml
+ ```
+
+### Step 2: Configure Values
+
+Create a `values.yaml` file to customize your installation. At minimum, you need to configure the UI access method.
+
+**Option A: Using Ingress (Recommended for production)**
+
+```yaml
+ui:
+ ingress:
+ enabled: true
+ hosts:
+ - host: prowler.example.com
+ paths:
+ - path: /
+ pathType: ImplementationSpecific
+```
+
+**Option B: Using authUrl (For proxy setups)**
+
+```yaml
+ui:
+ authUrl: prowler.example.com
+```
+
+> **Note:** See the [minimal installation example](./examples/minimal-installation/values.yaml) for a complete reference.
+
+### Step 3: Install the Chart
+
+Install Prowler App using Helm:
+
+```bash
+helm dependency update
+helm install prowler prowler/prowler-app -f values.yaml
+```
+
+### Using Existing PostgreSQL and Valkey Instances
+
+By default, this Chart uses Bitnami's Charts to deploy [PostgreSQL](https://artifacthub.io/packages/helm/bitnami/postgresql), [Neo4j](https://helm.neo4j.com/neo4j) and [Valkey official helm chart](https://valkey.io/valkey-helm/). **Note:** This default setup is not production-ready.
+
+To connect to existing PostgreSQL, Neo4j and Valkey instances:
+
+1. Create a `Secret` containing the correct database and message broker credentials
+2. Reference the secret in the [values.yaml](values.yaml) file api->secrets list
+
+## Contributing
+
+Feel free to contact the maintainer of this repository for any questions or concerns. Contributions are encouraged and appreciated.
diff --git a/contrib/k8s/helm/prowler-app/examples/minimal-installation/README.md b/contrib/k8s/helm/prowler-app/examples/minimal-installation/README.md
new file mode 100644
index 0000000000..e22f429b44
--- /dev/null
+++ b/contrib/k8s/helm/prowler-app/examples/minimal-installation/README.md
@@ -0,0 +1,46 @@
+# Minimal Installation Example
+
+This example demonstrates a minimal installation of Prowler in a Kubernetes cluster.
+
+## Installation
+
+To install Prowler using this example:
+
+1. First, create the required secret:
+```bash
+# Edit secret.yaml and set secure values before applying
+kubectl apply -f secret.yaml
+```
+
+1. Install the chart using the base values file:
+```bash
+# Basic installation
+helm install prowler prowler/prowler-app -f values.yaml
+```
+
+## Configuration
+
+The example contains the following configuration files:
+
+### `secret.yaml`
+Contains all required secrets for the Prowler installation. **Must be applied before installing the Helm chart**. Make sure to replace all placeholder values with secure values before applying.
+
+### `values.yaml`
+```yaml
+ui:
+ # Note: You should set either `authUrl` if you use prowler behind a proxy or enable `ingress`.
+
+ # Example with authUrl:
+ # authUrl: example.prowler.com
+
+ # Example with ingress:
+ ingress:
+ enabled: true
+ hosts:
+ - host: example.prowler.com
+ paths:
+ - path: /
+ pathType: ImplementationSpecific
+```
+
+Make sure to adjust the hostname in the values file to match your environment before installing.
diff --git a/contrib/k8s/helm/prowler-app/examples/minimal-installation/secrets.yaml b/contrib/k8s/helm/prowler-app/examples/minimal-installation/secrets.yaml
new file mode 100644
index 0000000000..2e379ef5c8
--- /dev/null
+++ b/contrib/k8s/helm/prowler-app/examples/minimal-installation/secrets.yaml
@@ -0,0 +1,58 @@
+apiVersion: v1
+kind: Secret
+type: Opaque
+metadata:
+ name: prowler-secret
+stringData:
+ # openssl genrsa -out private.pem 2048
+ DJANGO_TOKEN_SIGNING_KEY: |
+ -----BEGIN PRIVATE KEY-----
+ MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCIro0QiLAxw7rF
+ GO0NgAWJfkpYE5ysMGDCbId07HUrv+/SCoRjqKVzGJVIvmNP5oByzSehPgswW9v3
+ 3dqe2r9sCS1JyMa+XO3qfZCR0uRDcPCwZjIyr0QQLpWAymdBa8baeHsU1/3Orjcb
+ Vrr+lNx4HQJOiSn094iXPReW/25hYeq/SXs79V2CR87PGdoZAhb8IllAxJgdfkeB
+ /iWohY/1vfRTmIuMweWGXk0aKzPsBdvE/DqG4HjiNVEPh18G3vid0YTZNmm7u8vO
+ Cue3x9NQWGHA4QtxNtLtxlHcOEryqZ9ChO2nC+ew0Xl/v706XFNyLFicjisIKNQo
+ qdkaMS33AgMBAAECggEAGdJIChCYoL4mYafk2MEPyrrWFq+V0J3PGcvhB0DInfxD
+ tT2RZzZsE0NYqIZ3Qpf8OjPxwa9z863W74u1Cn+u3B0bti29BieONteD4VijEO6c
+ OecEorijth7m1Y7nVN+kkI9kSTrI0yvsczi+WOwMfpCUZ/vXtlSxNEkxVLBqzPCo
+ 9VxAFIjgWOj2rpw8nxPedves36PUrC5ghLqrOTe1jmw/Di0++47AXG+DsTXc00sc
+ 5+oybopm3Kimsxrqbf9s8SZf2A8NiwqcbLj8OtP2j2g4TCEgZYLD5Zmt+JN/wN4B
+ WsQG/Hwp4KPPm9QTHEpuuoPFP1CZWZeq8gPcV4apYQKBgQC+TuXjJCYhZqNIttTZ
+ z/i3hkKUEKQLkzTZnXaDzL5wHyEMVqM2E/WkilO0C9ZZwh0ENPzkp+JsHf7LEhHy
+ wSHOti81VzUCjN/YpCBKlOlClqSiDlOonImrobLei8xgvmA0VmGtirCXZyyzZUoV
+ OyPr17WpK6G/M5piX59MvKQg0QKBgQC33NBoQFD8A6FjrTopYmWfK099k9uQh9NE
+ bvUYsNAPunSDslmc/0PPHQC7fRX5Ime2BinXAN1PYtB/Fsu3jv/+FCUM5hVil0Dd
+ KBvt13+RYSCJKlhcGP1EkWoIg1F2XXBOZKJrC8VQ+Vyl2t06UcWQqy5M9J4VZaqI
+ fruOLU/URwKBgE55GjJfZZnASPRi78IhD94dbra/ZeWf/dr+IzCV7LEvJOGBmCtk
+ b5Y5s+o6N1krwetKLj3bPHJ4q+fwu5XuLZKfbTgBjcpPbL5YbzhRzx22IIzye2y7
+ n8k2FBvQaaY62lC6jeyRk9/am4Qd8D5w9I77k9z+MOQ20yJda8KoxsUBAoGBAIQ9
+ 5QPmppjsf4ry0C9t30uhWhYnX7fPiYviBpVQrwVxBVan076Q9xOjd6BicohzT4bj
+ XfqPW546o12VZsbKqqLzmEZzwpPb2EJ5E8V4xv8ojb86Xr03GArWUB55XQE2aY1o
+ 4kz99VitUg7UoWPN5ryL8sxU8NLRAdwU0w+K1a0HAoGAZaU7O94u9IIPZ6Ohobs2
+ Vjf/eV0brCKgX61b4z/YhuJdZsyTujhBZUihZwqR696kiFKuzmHx1ghE2ITvnPVN
+ q0iHxRZzBCnRQ+mQlS0trzphaCP0NVy3osFeAD9mJfnOnSmkU0ua4F81mkvke1eN
+ 6nnaoAdy2lmMr96/Tye2ty4=
+ -----END PRIVATE KEY-----
+
+ # openssl rsa -in private.pem -pubout -out public.pem
+ DJANGO_TOKEN_VERIFYING_KEY: |
+ -----BEGIN PUBLIC KEY-----
+ MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAiK6NEIiwMcO6xRjtDYAF
+ iX5KWBOcrDBgwmyHdOx1K7/v0gqEY6ilcxiVSL5jT+aAcs0noT4LMFvb993antq/
+ bAktScjGvlzt6n2QkdLkQ3DwsGYyMq9EEC6VgMpnQWvG2nh7FNf9zq43G1a6/pTc
+ eB0CTokp9PeIlz0Xlv9uYWHqv0l7O/VdgkfOzxnaGQIW/CJZQMSYHX5Hgf4lqIWP
+ 9b30U5iLjMHlhl5NGisz7AXbxPw6huB44jVRD4dfBt74ndGE2TZpu7vLzgrnt8fT
+ UFhhwOELcTbS7cZR3DhK8qmfQoTtpwvnsNF5f7+9OlxTcixYnI4rCCjUKKnZGjEt
+ 9wIDAQAB
+ -----END PUBLIC KEY-----
+
+ # openssl rand -base64 32
+ DJANGO_SECRETS_ENCRYPTION_KEY: "qYAIWnRK52aBT5YQkBoMEw08j7j3+QIPZXS6+A8Su44="
+
+ # openssl rand -base64 32
+ AUTH_SECRET: "CM9w3Nco2P1RdHaYmD+fmy2nJmSofusdHd4g7Z4KDG4="
+
+ # Unfortunatelly, we need to duplicate the password in two different keys because the Neo4j Helm Chart expects the password in the NEO4J_AUTH key and the application expects it in the NEO4J_PASSWORD key.
+ NEO4J_PASSWORD: "prowler-password-fake"
+ NEO4J_AUTH: "neo4j/prowler-password-fake"
diff --git a/contrib/k8s/helm/prowler-app/examples/minimal-installation/values.yaml b/contrib/k8s/helm/prowler-app/examples/minimal-installation/values.yaml
new file mode 100644
index 0000000000..9ac8dda9e9
--- /dev/null
+++ b/contrib/k8s/helm/prowler-app/examples/minimal-installation/values.yaml
@@ -0,0 +1,11 @@
+ui:
+ ingress:
+ enabled: true
+ hosts:
+ - host: 127.0.0.1.nip.io
+ paths:
+ - path: /
+ pathType: ImplementationSpecific
+
+# or use authUrl if you use prowler behind a proxy
+# authUrl: 127.0.0.1.nip.io
diff --git a/contrib/k8s/helm/prowler-app/templates/_helpers.tpl b/contrib/k8s/helm/prowler-app/templates/_helpers.tpl
new file mode 100644
index 0000000000..7698fbfa18
--- /dev/null
+++ b/contrib/k8s/helm/prowler-app/templates/_helpers.tpl
@@ -0,0 +1,134 @@
+{{/*
+Expand the name of the chart.
+*/}}
+{{- define "prowler.name" -}}
+{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
+{{- end }}
+
+{{/*
+Create a default fully qualified app name.
+We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
+If release name contains chart name it will be used as a full name.
+*/}}
+{{- define "prowler.fullname" -}}
+{{- if .Values.fullnameOverride }}
+{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
+{{- else }}
+{{- $name := default .Chart.Name .Values.nameOverride }}
+{{- if contains $name .Release.Name }}
+{{- .Release.Name | trunc 63 | trimSuffix "-" }}
+{{- else }}
+{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
+{{- end }}
+{{- end }}
+{{- end }}
+
+{{/*
+Create chart name and version as used by the chart label.
+*/}}
+{{- define "prowler.chart" -}}
+{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
+{{- end }}
+
+{{/*
+Common labels
+*/}}
+{{- define "prowler.labels" -}}
+helm.sh/chart: {{ include "prowler.chart" . }}
+app.kubernetes.io/instance: {{ .Release.Name }}
+{{- if .Chart.AppVersion }}
+app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
+{{- end }}
+app.kubernetes.io/managed-by: {{ .Release.Service }}
+{{- end }}
+
+{{/*
+Django environment variables for api, worker, and worker_beat.
+*/}}
+{{- define "prowler.django.env" -}}
+- name: DJANGO_TOKEN_SIGNING_KEY
+ valueFrom:
+ secretKeyRef:
+ name: {{ .Values.djangoTokenSigningKey.secretKeyRef.name }}
+ key: {{ .Values.djangoTokenSigningKey.secretKeyRef.key }}
+- name: DJANGO_TOKEN_VERIFYING_KEY
+ valueFrom:
+ secretKeyRef:
+ name: {{ .Values.djangoTokenVerifyingKey.secretKeyRef.name }}
+ key: {{ .Values.djangoTokenVerifyingKey.secretKeyRef.key }}
+- name: DJANGO_SECRETS_ENCRYPTION_KEY
+ valueFrom:
+ secretKeyRef:
+ name: {{ .Values.djangoSecretsEncryptionKey.secretKeyRef.name }}
+ key: {{ .Values.djangoSecretsEncryptionKey.secretKeyRef.key }}
+{{- end }}
+
+
+{{/*
+PostgreSQL environment variables for api, worker, and worker_beat.
+Outputs nothing when postgresql.enabled is false.
+*/}}
+{{- define "prowler.postgresql.env" -}}
+{{- if .Values.postgresql.enabled }}
+{{- if .Values.postgresql.auth.username }}
+- name: POSTGRES_USER
+ value: {{ .Values.postgresql.auth.username | quote }}
+{{- end }}
+- name: POSTGRES_PASSWORD
+{{- if .Values.postgresql.auth.existingSecret }}
+ valueFrom:
+ secretKeyRef:
+ name: {{ .Values.postgresql.auth.existingSecret }}
+ key: {{ required "postgresql.auth.secretKeys.userPasswordKey is required when using an existing secret" .Values.postgresql.auth.secretKeys.userPasswordKey }}
+{{- else if .Values.postgresql.auth.password }}
+ value: {{ .Values.postgresql.auth.password | quote }}
+{{- else }}
+ valueFrom:
+ secretKeyRef:
+ name: {{ .Release.Name }}-postgresql
+ key: password
+{{- end }}
+- name: POSTGRES_DB
+ value: {{ .Values.postgresql.auth.database | quote }}
+- name: POSTGRES_HOST
+ value: {{ .Release.Name }}-postgresql
+- name: POSTGRES_PORT
+ value: "5432"
+- name: POSTGRES_ADMIN_USER
+ value: postgres
+- name: POSTGRES_ADMIN_PASSWORD
+{{- if .Values.postgresql.auth.existingSecret }}
+ valueFrom:
+ secretKeyRef:
+ name: {{ .Values.postgresql.auth.existingSecret }}
+ key: {{ required "postgresql.auth.secretKeys.adminPasswordKey is required when using an existing secret" .Values.postgresql.auth.secretKeys.adminPasswordKey }}
+{{- else if .Values.postgresql.auth.postgresPassword }}
+ value: {{ .Values.postgresql.auth.postgresPassword | quote }}
+{{- else }}
+ valueFrom:
+ secretKeyRef:
+ name: {{ .Release.Name }}-postgresql
+ key: postgres-password
+{{- end }}
+{{- end }}
+{{- end }}
+
+{{/*
+Neo4j environment variables for api, worker, and worker_beat.
+Outputs nothing when neo4j.enabled is false.
+*/}}
+{{- define "prowler.neo4j.env" -}}
+{{- if .Values.neo4j.enabled }}
+- name: NEO4J_HOST
+ value: {{ .Release.Name }}
+- name: NEO4J_PORT
+ value: "7687"
+- name: NEO4J_USER
+ value: "neo4j"
+- name: NEO4J_PASSWORD
+ valueFrom:
+ secretKeyRef:
+ name: {{ required "neo4j.neo4j.passwordFromSecret is required" .Values.neo4j.neo4j.passwordFromSecret }}
+ key: NEO4J_PASSWORD
+{{- end }}
+{{- end }}
diff --git a/contrib/k8s/helm/prowler-app/templates/api/_helpers.tpl b/contrib/k8s/helm/prowler-app/templates/api/_helpers.tpl
new file mode 100644
index 0000000000..55ac97f0d8
--- /dev/null
+++ b/contrib/k8s/helm/prowler-app/templates/api/_helpers.tpl
@@ -0,0 +1,10 @@
+{{/*
+Create the name of the service account to use
+*/}}
+{{- define "prowler.api.serviceAccountName" -}}
+{{- if .Values.api.serviceAccount.create }}
+{{- default (printf "%s-%s" (include "prowler.fullname" .) "api") .Values.api.serviceAccount.name }}
+{{- else }}
+{{- default "default" .Values.api.serviceAccount.name }}
+{{- end }}
+{{- end }}
diff --git a/contrib/k8s/helm/prowler-app/templates/api/configmap.yaml b/contrib/k8s/helm/prowler-app/templates/api/configmap.yaml
new file mode 100644
index 0000000000..8e219a9271
--- /dev/null
+++ b/contrib/k8s/helm/prowler-app/templates/api/configmap.yaml
@@ -0,0 +1,10 @@
+kind: ConfigMap
+apiVersion: v1
+metadata:
+ name: {{ include "prowler.fullname" . }}-api
+ labels:
+ {{- include "prowler.labels" . | nindent 4 }}
+data:
+ {{- range $key, $value := .Values.api.djangoConfig }}
+ {{ $key }}: {{ $value | quote }}
+ {{- end }}
\ No newline at end of file
diff --git a/contrib/k8s/helm/prowler-app/templates/api/deployment.yaml b/contrib/k8s/helm/prowler-app/templates/api/deployment.yaml
new file mode 100644
index 0000000000..f7a16b66ae
--- /dev/null
+++ b/contrib/k8s/helm/prowler-app/templates/api/deployment.yaml
@@ -0,0 +1,105 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: {{ include "prowler.fullname" . }}-api
+ labels:
+ {{- include "prowler.labels" . | nindent 4 }}
+spec:
+ {{- if not .Values.api.autoscaling.enabled }}
+ replicas: {{ .Values.api.replicaCount }}
+ {{- end }}
+ selector:
+ matchLabels:
+ app.kubernetes.io/name: {{ include "prowler.fullname" . }}-api
+ template:
+ metadata:
+ annotations:
+ secret-hash: "{{ printf "%s%s%s" (.Files.Get "templates/api/configmap.yaml" | sha256sum) (.Files.Get "templates/api/secret-valkey.yaml" | sha256sum) | sha256sum }}"
+ {{- with .Values.api.podAnnotations }}
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ labels:
+ {{- include "prowler.labels" . | nindent 8 }}
+ app.kubernetes.io/name: {{ include "prowler.fullname" . }}-api
+ {{- with .Values.api.podLabels }}
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ spec:
+ {{- with .Values.api.imagePullSecrets }}
+ imagePullSecrets:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ serviceAccountName: {{ include "prowler.api.serviceAccountName" . }}
+ {{- with .Values.api.podSecurityContext }}
+ securityContext:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ containers:
+ - name: api
+ {{- with .Values.api.securityContext }}
+ securityContext:
+ {{- toYaml . | nindent 12 }}
+ {{- end }}
+ image: "{{ .Values.api.image.repository }}:{{ .Values.api.image.tag | default .Chart.AppVersion }}"
+ imagePullPolicy: {{ .Values.api.image.pullPolicy }}
+ {{- with .Values.api.command }}
+ command:
+ {{- toYaml . | nindent 12 }}
+ {{- end }}
+ {{- with .Values.api.args }}
+ args:
+ {{- toYaml . | nindent 12 }}
+ {{- end }}
+ ports:
+ - name: http
+ containerPort: {{ .Values.api.service.port }}
+ protocol: TCP
+ envFrom:
+ - configMapRef:
+ name: {{ include "prowler.fullname" . }}-api
+ {{- if .Values.valkey.enabled }}
+ - secretRef:
+ name: {{ include "prowler.fullname" . }}-api-valkey
+ {{- end }}
+ {{- with .Values.api.secrets }}
+ {{- range $index, $secret := . }}
+ - secretRef:
+ name: {{ $secret }}
+ {{- end }}
+ {{- end }}
+ env:
+ {{- include "prowler.django.env" . | nindent 12 }}
+ {{- include "prowler.postgresql.env" . | nindent 12 }}
+ {{- include "prowler.neo4j.env" . | nindent 12 }}
+ {{- with .Values.api.livenessProbe }}
+ livenessProbe:
+ {{- toYaml . | nindent 12 }}
+ {{- end }}
+ {{- with .Values.api.readinessProbe }}
+ readinessProbe:
+ {{- toYaml . | nindent 12 }}
+ {{- end }}
+ {{- with .Values.api.resources }}
+ resources:
+ {{- toYaml . | nindent 12 }}
+ {{- end }}
+ {{- with .Values.api.volumeMounts }}
+ volumeMounts:
+ {{- toYaml . | nindent 12 }}
+ {{- end }}
+ {{- with .Values.api.volumes }}
+ volumes:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- with .Values.api.nodeSelector }}
+ nodeSelector:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- with .Values.api.affinity }}
+ affinity:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- with .Values.api.tolerations }}
+ tolerations:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
diff --git a/contrib/k8s/helm/prowler-app/templates/api/hpa.yaml b/contrib/k8s/helm/prowler-app/templates/api/hpa.yaml
new file mode 100644
index 0000000000..c3d77d7e44
--- /dev/null
+++ b/contrib/k8s/helm/prowler-app/templates/api/hpa.yaml
@@ -0,0 +1,32 @@
+{{- if .Values.api.autoscaling.enabled }}
+apiVersion: autoscaling/v2
+kind: HorizontalPodAutoscaler
+metadata:
+ name: {{ include "prowler.fullname" . }}-api
+ labels:
+ {{- include "prowler.labels" . | nindent 4 }}
+spec:
+ scaleTargetRef:
+ apiVersion: apps/v1
+ kind: Deployment
+ name: {{ include "prowler.fullname" . }}-api
+ minReplicas: {{ .Values.api.autoscaling.minReplicas }}
+ maxReplicas: {{ .Values.api.autoscaling.maxReplicas }}
+ metrics:
+ {{- if .Values.api.autoscaling.targetCPUUtilizationPercentage }}
+ - type: Resource
+ resource:
+ name: cpu
+ target:
+ type: Utilization
+ averageUtilization: {{ .Values.api.autoscaling.targetCPUUtilizationPercentage }}
+ {{- end }}
+ {{- if .Values.api.autoscaling.targetMemoryUtilizationPercentage }}
+ - type: Resource
+ resource:
+ name: memory
+ target:
+ type: Utilization
+ averageUtilization: {{ .Values.api.autoscaling.targetMemoryUtilizationPercentage }}
+ {{- end }}
+{{- end }}
diff --git a/contrib/k8s/helm/prowler-app/templates/api/ingress.yaml b/contrib/k8s/helm/prowler-app/templates/api/ingress.yaml
new file mode 100644
index 0000000000..4118d9cd7a
--- /dev/null
+++ b/contrib/k8s/helm/prowler-app/templates/api/ingress.yaml
@@ -0,0 +1,43 @@
+{{- if .Values.api.ingress.enabled -}}
+apiVersion: networking.k8s.io/v1
+kind: Ingress
+metadata:
+ name: {{ include "prowler.fullname" . }}-api
+ labels:
+ {{- include "prowler.labels" . | nindent 4 }}
+ {{- with .Values.api.ingress.annotations }}
+ annotations:
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
+spec:
+ {{- with .Values.api.ingress.className }}
+ ingressClassName: {{ . }}
+ {{- end }}
+ {{- if .Values.api.ingress.tls }}
+ tls:
+ {{- range .Values.api.ingress.tls }}
+ - hosts:
+ {{- range .hosts }}
+ - {{ . | quote }}
+ {{- end }}
+ secretName: {{ .secretName }}
+ {{- end }}
+ {{- end }}
+ rules:
+ {{- range .Values.api.ingress.hosts }}
+ - host: {{ .host | quote }}
+ http:
+ paths:
+ {{- range .paths }}
+ - path: {{ .path }}
+ {{- with .pathType }}
+ pathType: {{ . }}
+ {{- end }}
+ backend:
+ service:
+ name: {{ include "prowler.fullname" $ }}-api
+ port:
+ number: {{ $.Values.api.service.port }}
+ {{- end }}
+ {{- end }}
+{{- end }}
diff --git a/contrib/k8s/helm/prowler-app/templates/api/role.yaml b/contrib/k8s/helm/prowler-app/templates/api/role.yaml
new file mode 100644
index 0000000000..172b035076
--- /dev/null
+++ b/contrib/k8s/helm/prowler-app/templates/api/role.yaml
@@ -0,0 +1,29 @@
+# https://docs.prowler.com/projects/prowler-open-source/en/latest/tutorials/prowler-app/#step-44-kubernetes-credentials
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ name: {{ include "prowler.fullname" . }}-api
+ labels:
+ {{- include "prowler.labels" . | nindent 4 }}
+rules:
+- apiGroups: [""]
+ resources: ["pods", "configmaps", "nodes", "namespaces"]
+ verbs: ["get", "list", "watch"]
+- apiGroups: ["rbac.authorization.k8s.io"]
+ resources: ["clusterrolebindings", "rolebindings", "clusterroles", "roles"]
+ verbs: ["get", "list", "watch"]
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+ name: {{ include "prowler.fullname" . }}-api
+ labels:
+ {{- include "prowler.labels" . | nindent 4 }}
+roleRef:
+ apiGroup: rbac.authorization.k8s.io
+ kind: ClusterRole
+ name: {{ include "prowler.fullname" . }}-api
+subjects:
+- kind: ServiceAccount
+ name: {{ include "prowler.api.serviceAccountName" . }}
+ namespace: {{ .Release.Namespace }}
\ No newline at end of file
diff --git a/contrib/k8s/helm/prowler-app/templates/api/secret-valkey.yaml b/contrib/k8s/helm/prowler-app/templates/api/secret-valkey.yaml
new file mode 100644
index 0000000000..7778d06731
--- /dev/null
+++ b/contrib/k8s/helm/prowler-app/templates/api/secret-valkey.yaml
@@ -0,0 +1,13 @@
+{{- if .Values.valkey.enabled -}}
+apiVersion: v1
+kind: Secret
+metadata:
+ name: {{ include "prowler.fullname" . }}-api-valkey
+ labels:
+ {{- include "prowler.labels" . | nindent 4 }}
+type: Opaque
+stringData:
+ VALKEY_HOST: "{{ include "prowler.fullname" . }}-valkey"
+ VALKEY_PORT: "6379"
+ VALKEY_DB: "0"
+{{- end -}}
diff --git a/contrib/k8s/helm/prowler-app/templates/api/service.yaml b/contrib/k8s/helm/prowler-app/templates/api/service.yaml
new file mode 100644
index 0000000000..9a42979306
--- /dev/null
+++ b/contrib/k8s/helm/prowler-app/templates/api/service.yaml
@@ -0,0 +1,15 @@
+apiVersion: v1
+kind: Service
+metadata:
+ name: {{ include "prowler.fullname" . }}-api
+ labels:
+ {{- include "prowler.labels" . | nindent 4 }}
+spec:
+ type: {{ .Values.api.service.type }}
+ ports:
+ - port: {{ .Values.api.service.port }}
+ targetPort: http
+ protocol: TCP
+ name: http
+ selector:
+ app.kubernetes.io/name: {{ include "prowler.fullname" . }}-api
diff --git a/contrib/k8s/helm/prowler-app/templates/api/serviceaccount.yaml b/contrib/k8s/helm/prowler-app/templates/api/serviceaccount.yaml
new file mode 100644
index 0000000000..4d76d7f54e
--- /dev/null
+++ b/contrib/k8s/helm/prowler-app/templates/api/serviceaccount.yaml
@@ -0,0 +1,13 @@
+{{- if .Values.api.serviceAccount.create -}}
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+ name: {{ include "prowler.api.serviceAccountName" . }}
+ labels:
+ {{- include "prowler.labels" . | nindent 4 }}
+ {{- with .Values.api.serviceAccount.annotations }}
+ annotations:
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
+automountServiceAccountToken: {{ .Values.api.serviceAccount.automount }}
+{{- end }}
diff --git a/contrib/k8s/helm/prowler-app/templates/ui/_helpers.tpl b/contrib/k8s/helm/prowler-app/templates/ui/_helpers.tpl
new file mode 100644
index 0000000000..8bdf93ba5f
--- /dev/null
+++ b/contrib/k8s/helm/prowler-app/templates/ui/_helpers.tpl
@@ -0,0 +1,10 @@
+{{/*
+Create the name of the service account to use
+*/}}
+{{- define "prowler.ui.serviceAccountName" -}}
+{{- if .Values.ui.serviceAccount.create }}
+{{- default (printf "%s-%s" (include "prowler.fullname" .) "ui") .Values.ui.serviceAccount.name }}
+{{- else }}
+{{- default "default" .Values.ui.serviceAccount.name }}
+{{- end }}
+{{- end }}
diff --git a/contrib/k8s/helm/prowler-app/templates/ui/configmap.yaml b/contrib/k8s/helm/prowler-app/templates/ui/configmap.yaml
new file mode 100644
index 0000000000..38d6e65ee3
--- /dev/null
+++ b/contrib/k8s/helm/prowler-app/templates/ui/configmap.yaml
@@ -0,0 +1,18 @@
+kind: ConfigMap
+apiVersion: v1
+metadata:
+ name: {{ include "prowler.fullname" . }}-ui
+data:
+ PROWLER_UI_VERSION: "stable"
+ {{- if .Values.ui.ingress.enabled }}
+ {{- with (first .Values.ui.ingress.hosts) }}
+ AUTH_URL: "https://{{ .host }}"
+ {{- end }}
+ {{- else }}
+ AUTH_URL: {{ .Values.ui.authUrl | quote }}
+ {{- end }}
+ API_BASE_URL: "http://{{ include "prowler.fullname" . }}-api:{{ .Values.api.service.port }}/api/v1"
+ NEXT_PUBLIC_API_BASE_URL: "http://{{ include "prowler.fullname" . }}-api:{{ .Values.api.service.port }}/api/v1"
+ NEXT_PUBLIC_API_DOCS_URL: "http://{{ include "prowler.fullname" . }}-api:{{ .Values.api.service.port }}/api/v1/docs"
+ AUTH_TRUST_HOST: "true"
+ UI_PORT: {{ .Values.ui.service.port | quote }}
diff --git a/contrib/k8s/helm/prowler-app/templates/ui/deployment.yaml b/contrib/k8s/helm/prowler-app/templates/ui/deployment.yaml
new file mode 100644
index 0000000000..f7bf2c17fe
--- /dev/null
+++ b/contrib/k8s/helm/prowler-app/templates/ui/deployment.yaml
@@ -0,0 +1,95 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: {{ include "prowler.fullname" . }}-ui
+ labels:
+ {{- include "prowler.labels" . | nindent 4 }}
+spec:
+ {{- if not .Values.ui.autoscaling.enabled }}
+ replicas: {{ .Values.ui.replicaCount }}
+ {{- end }}
+ selector:
+ matchLabels:
+ app.kubernetes.io/name: {{ include "prowler.fullname" . }}-ui
+ template:
+ metadata:
+ annotations:
+ secret-hash: {{ .Files.Get "templates/ui/configmap.yaml" | sha256sum }}
+ {{- with .Values.ui.podAnnotations }}
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ labels:
+ {{- include "prowler.labels" . | nindent 8 }}
+ app.kubernetes.io/name: {{ include "prowler.fullname" . }}-ui
+ {{- with .Values.ui.podLabels }}
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ spec:
+ {{- with .Values.ui.imagePullSecrets }}
+ imagePullSecrets:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ serviceAccountName: {{ include "prowler.ui.serviceAccountName" . }}
+ {{- with .Values.ui.podSecurityContext }}
+ securityContext:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ containers:
+ - name: ui
+ {{- with .Values.ui.securityContext }}
+ securityContext:
+ {{- toYaml . | nindent 12 }}
+ {{- end }}
+ image: "{{ .Values.ui.image.repository }}:{{ .Values.ui.image.tag | default .Chart.AppVersion }}"
+ imagePullPolicy: {{ .Values.ui.image.pullPolicy }}
+ ports:
+ - name: http
+ containerPort: {{ .Values.ui.service.port }}
+ protocol: TCP
+ env:
+ - name: AUTH_SECRET
+ valueFrom:
+ secretKeyRef:
+ name: {{ .Values.ui.authSecret.secretKeyRef.name }}
+ key: {{ .Values.ui.authSecret.secretKeyRef.key }}
+ envFrom:
+ - configMapRef:
+ name: {{ include "prowler.fullname" . }}-ui
+ {{- with .Values.ui.secrets }}
+ {{- range $index, $secret := . }}
+ - secretRef:
+ name: {{ $secret }}
+ {{- end }}
+ {{- end }}
+ {{- with .Values.ui.livenessProbe }}
+ livenessProbe:
+ {{- toYaml . | nindent 12 }}
+ {{- end }}
+ {{- with .Values.ui.readinessProbe }}
+ readinessProbe:
+ {{- toYaml . | nindent 12 }}
+ {{- end }}
+ {{- with .Values.ui.resources }}
+ resources:
+ {{- toYaml . | nindent 12 }}
+ {{- end }}
+ {{- with .Values.ui.volumeMounts }}
+ volumeMounts:
+ {{- toYaml . | nindent 12 }}
+ {{- end }}
+ {{- with .Values.ui.volumes }}
+ volumes:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- with .Values.ui.nodeSelector }}
+ nodeSelector:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- with .Values.ui.affinity }}
+ affinity:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- with .Values.ui.tolerations }}
+ tolerations:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
diff --git a/contrib/k8s/helm/prowler-app/templates/ui/hpa.yaml b/contrib/k8s/helm/prowler-app/templates/ui/hpa.yaml
new file mode 100644
index 0000000000..7c6716ef1f
--- /dev/null
+++ b/contrib/k8s/helm/prowler-app/templates/ui/hpa.yaml
@@ -0,0 +1,32 @@
+{{- if .Values.ui.autoscaling.enabled }}
+apiVersion: autoscaling/v2
+kind: HorizontalPodAutoscaler
+metadata:
+ name: {{ include "prowler.fullname" . }}-ui
+ labels:
+ {{- include "prowler.labels" . | nindent 4 }}
+spec:
+ scaleTargetRef:
+ apiVersion: apps/v1
+ kind: Deployment
+ name: {{ include "prowler.fullname" . }}-ui
+ minReplicas: {{ .Values.ui.autoscaling.minReplicas }}
+ maxReplicas: {{ .Values.ui.autoscaling.maxReplicas }}
+ metrics:
+ {{- if .Values.ui.autoscaling.targetCPUUtilizationPercentage }}
+ - type: Resource
+ resource:
+ name: cpu
+ target:
+ type: Utilization
+ averageUtilization: {{ .Values.ui.autoscaling.targetCPUUtilizationPercentage }}
+ {{- end }}
+ {{- if .Values.ui.autoscaling.targetMemoryUtilizationPercentage }}
+ - type: Resource
+ resource:
+ name: memory
+ target:
+ type: Utilization
+ averageUtilization: {{ .Values.ui.autoscaling.targetMemoryUtilizationPercentage }}
+ {{- end }}
+{{- end }}
diff --git a/contrib/k8s/helm/prowler-app/templates/ui/ingress.yaml b/contrib/k8s/helm/prowler-app/templates/ui/ingress.yaml
new file mode 100644
index 0000000000..74dcecabe1
--- /dev/null
+++ b/contrib/k8s/helm/prowler-app/templates/ui/ingress.yaml
@@ -0,0 +1,43 @@
+{{- if .Values.ui.ingress.enabled -}}
+apiVersion: networking.k8s.io/v1
+kind: Ingress
+metadata:
+ name: {{ include "prowler.fullname" . }}-ui
+ labels:
+ {{- include "prowler.labels" . | nindent 4 }}
+ {{- with .Values.ui.ingress.annotations }}
+ annotations:
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
+spec:
+ {{- with .Values.ui.ingress.className }}
+ ingressClassName: {{ . }}
+ {{- end }}
+ {{- if .Values.ui.ingress.tls }}
+ tls:
+ {{- range .Values.ui.ingress.tls }}
+ - hosts:
+ {{- range .hosts }}
+ - {{ . | quote }}
+ {{- end }}
+ secretName: {{ .secretName }}
+ {{- end }}
+ {{- end }}
+ rules:
+ {{- range .Values.ui.ingress.hosts }}
+ - host: {{ .host | quote }}
+ http:
+ paths:
+ {{- range .paths }}
+ - path: {{ .path }}
+ {{- with .pathType }}
+ pathType: {{ . }}
+ {{- end }}
+ backend:
+ service:
+ name: {{ include "prowler.fullname" $ }}-ui
+ port:
+ number: {{ $.Values.ui.service.port }}
+ {{- end }}
+ {{- end }}
+{{- end }}
diff --git a/contrib/k8s/helm/prowler-app/templates/ui/service.yaml b/contrib/k8s/helm/prowler-app/templates/ui/service.yaml
new file mode 100644
index 0000000000..9b845e5b5f
--- /dev/null
+++ b/contrib/k8s/helm/prowler-app/templates/ui/service.yaml
@@ -0,0 +1,15 @@
+apiVersion: v1
+kind: Service
+metadata:
+ name: {{ include "prowler.fullname" . }}-ui
+ labels:
+ {{- include "prowler.labels" . | nindent 4 }}
+spec:
+ type: {{ .Values.ui.service.type }}
+ ports:
+ - port: {{ .Values.ui.service.port }}
+ targetPort: http
+ protocol: TCP
+ name: http
+ selector:
+ app.kubernetes.io/name: {{ include "prowler.fullname" . }}-ui
diff --git a/contrib/k8s/helm/prowler-app/templates/ui/serviceaccount.yaml b/contrib/k8s/helm/prowler-app/templates/ui/serviceaccount.yaml
new file mode 100644
index 0000000000..91b176a64e
--- /dev/null
+++ b/contrib/k8s/helm/prowler-app/templates/ui/serviceaccount.yaml
@@ -0,0 +1,13 @@
+{{- if .Values.ui.serviceAccount.create -}}
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+ name: {{ include "prowler.ui.serviceAccountName" . }}
+ labels:
+ {{- include "prowler.labels" . | nindent 4 }}
+ {{- with .Values.ui.serviceAccount.annotations }}
+ annotations:
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
+automountServiceAccountToken: {{ .Values.ui.serviceAccount.automount }}
+{{- end }}
diff --git a/contrib/k8s/helm/prowler-app/templates/worker/_helpers.tpl b/contrib/k8s/helm/prowler-app/templates/worker/_helpers.tpl
new file mode 100644
index 0000000000..3a99d42cb6
--- /dev/null
+++ b/contrib/k8s/helm/prowler-app/templates/worker/_helpers.tpl
@@ -0,0 +1,10 @@
+{{/*
+Create the name of the service account to use
+*/}}
+{{- define "prowler.worker.serviceAccountName" -}}
+{{- if .Values.worker.serviceAccount.create }}
+{{- default (printf "%s-%s" (include "prowler.fullname" .) "worker") .Values.worker.serviceAccount.name }}
+{{- else }}
+{{- default "default" .Values.worker.serviceAccount.name }}
+{{- end }}
+{{- end }}
diff --git a/contrib/k8s/helm/prowler-app/templates/worker/deployment.yaml b/contrib/k8s/helm/prowler-app/templates/worker/deployment.yaml
new file mode 100644
index 0000000000..6c11a28f9b
--- /dev/null
+++ b/contrib/k8s/helm/prowler-app/templates/worker/deployment.yaml
@@ -0,0 +1,101 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: {{ include "prowler.fullname" . }}-worker
+ labels:
+ {{- include "prowler.labels" . | nindent 4 }}
+spec:
+ {{- if not .Values.worker.autoscaling.enabled }}
+ replicas: {{ .Values.worker.replicaCount }}
+ {{- end }}
+ selector:
+ matchLabels:
+ app.kubernetes.io/name: {{ include "prowler.fullname" . }}-worker
+ template:
+ metadata:
+ annotations:
+ secret-hash: "{{ printf "%s%s%s" (.Files.Get "templates/api/configmap.yaml" | sha256sum) (.Files.Get "templates/api/secret-valkey.yaml" | sha256sum) | sha256sum }}"
+ {{- with .Values.worker.podAnnotations }}
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ labels:
+ {{- include "prowler.labels" . | nindent 8 }}
+ app.kubernetes.io/name: {{ include "prowler.fullname" . }}-worker
+ {{- with .Values.worker.podLabels }}
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ spec:
+ {{- with .Values.worker.imagePullSecrets }}
+ imagePullSecrets:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ serviceAccountName: {{ include "prowler.worker.serviceAccountName" . }}
+ {{- with .Values.worker.podSecurityContext }}
+ securityContext:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ containers:
+ - name: worker
+ {{- with .Values.worker.securityContext }}
+ securityContext:
+ {{- toYaml . | nindent 12 }}
+ {{- end }}
+ image: "{{ .Values.worker.image.repository }}:{{ .Values.worker.image.tag | default .Chart.AppVersion }}"
+ imagePullPolicy: {{ .Values.worker.image.pullPolicy }}
+ {{- with .Values.worker.command }}
+ command:
+ {{- toYaml . | nindent 12 }}
+ {{- end }}
+ {{- with .Values.worker.args }}
+ args:
+ {{- toYaml . | nindent 12 }}
+ {{- end }}
+ envFrom:
+ - configMapRef:
+ name: {{ include "prowler.fullname" . }}-api
+ {{- if .Values.valkey.enabled }}
+ - secretRef:
+ name: {{ include "prowler.fullname" . }}-api-valkey
+ {{- end }}
+ {{- with .Values.api.secrets }}
+ {{- range $index, $secret := . }}
+ - secretRef:
+ name: {{ $secret }}
+ {{- end }}
+ {{- end }}
+ env:
+ {{- include "prowler.django.env" . | nindent 12 }}
+ {{- include "prowler.postgresql.env" . | nindent 12 }}
+ {{- include "prowler.neo4j.env" . | nindent 12 }}
+ {{- with .Values.worker.livenessProbe }}
+ livenessProbe:
+ {{- toYaml . | nindent 12 }}
+ {{- end }}
+ {{- with .Values.worker.readinessProbe }}
+ readinessProbe:
+ {{- toYaml . | nindent 12 }}
+ {{- end }}
+ {{- with .Values.worker.resources }}
+ resources:
+ {{- toYaml . | nindent 12 }}
+ {{- end }}
+ {{- with .Values.worker.volumeMounts }}
+ volumeMounts:
+ {{- toYaml . | nindent 12 }}
+ {{- end }}
+ {{- with .Values.worker.volumes }}
+ volumes:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- with .Values.worker.nodeSelector }}
+ nodeSelector:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- with .Values.worker.affinity }}
+ affinity:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- with .Values.worker.tolerations }}
+ tolerations:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
diff --git a/contrib/k8s/helm/prowler-app/templates/worker/hpa.yaml b/contrib/k8s/helm/prowler-app/templates/worker/hpa.yaml
new file mode 100644
index 0000000000..d77ab3f47e
--- /dev/null
+++ b/contrib/k8s/helm/prowler-app/templates/worker/hpa.yaml
@@ -0,0 +1,32 @@
+{{- if .Values.worker.autoscaling.enabled }}
+apiVersion: autoscaling/v2
+kind: HorizontalPodAutoscaler
+metadata:
+ name: {{ include "prowler.fullname" . }}-worker
+ labels:
+ {{- include "prowler.labels" . | nindent 4 }}
+spec:
+ scaleTargetRef:
+ apiVersion: apps/v1
+ kind: Deployment
+ name: {{ include "prowler.fullname" . }}-worker
+ minReplicas: {{ .Values.worker.autoscaling.minReplicas }}
+ maxReplicas: {{ .Values.worker.autoscaling.maxReplicas }}
+ metrics:
+ {{- if .Values.worker.autoscaling.targetCPUUtilizationPercentage }}
+ - type: Resource
+ resource:
+ name: cpu
+ target:
+ type: Utilization
+ averageUtilization: {{ .Values.worker.autoscaling.targetCPUUtilizationPercentage }}
+ {{- end }}
+ {{- if .Values.worker.autoscaling.targetMemoryUtilizationPercentage }}
+ - type: Resource
+ resource:
+ name: memory
+ target:
+ type: Utilization
+ averageUtilization: {{ .Values.worker.autoscaling.targetMemoryUtilizationPercentage }}
+ {{- end }}
+{{- end }}
diff --git a/contrib/k8s/helm/prowler-app/templates/worker/scaled-object.yaml b/contrib/k8s/helm/prowler-app/templates/worker/scaled-object.yaml
new file mode 100644
index 0000000000..98ae3ae9d5
--- /dev/null
+++ b/contrib/k8s/helm/prowler-app/templates/worker/scaled-object.yaml
@@ -0,0 +1,32 @@
+{{- if .Values.worker.keda.enabled }}
+apiVersion: keda.sh/v1alpha1
+kind: ScaledObject
+metadata:
+ name: {{ include "prowler.fullname" . }}-worker
+ namespace: {{ $.Release.Namespace }}
+ labels:
+ {{- include "prowler.labels" . | nindent 4 }}
+spec:
+ scaleTargetRef:
+ name: {{ include "prowler.fullname" . }}-worker
+ envSourceContainerName: worker
+ kind: Deployment
+ minReplicaCount: {{ .Values.worker.keda.minReplicas }}
+ maxReplicaCount: {{ .Values.worker.keda.maxReplicas }}
+ pollingInterval: {{ .Values.worker.keda.pollingInterval }}
+ cooldownPeriod: {{ .Values.worker.keda.cooldownPeriod }}
+ triggers:
+ - type: {{ .Values.worker.keda.triggerType }}
+ metadata:
+ userName: "postgres"
+ passwordFromEnv: POSTGRES_ADMIN_PASSWORD
+ host: {{ .Release.Name }}-postgresql
+ port: {{ .Values.postgresql.port | quote }}
+ dbName: {{ .Values.postgresql.auth.database | quote }}
+ sslmode: disable
+ # Query for KEDA to count the number of scans that are in executing, available, or scheduled states,
+ # where the scheduled time is within the last 2 hours and is before NOW(). Used for scaling workers.
+ query: >-
+ SELECT COUNT(*) FROM scans WHERE ((state='executing' OR state='available' OR state='scheduled') and scheduled_at < NOW() and scheduled_at > NOW() - INTERVAL '2 hours')
+ targetQueryValue: "1"
+{{- end }}
diff --git a/contrib/k8s/helm/prowler-app/templates/worker/serviceaccount.yaml b/contrib/k8s/helm/prowler-app/templates/worker/serviceaccount.yaml
new file mode 100644
index 0000000000..8974d3ce04
--- /dev/null
+++ b/contrib/k8s/helm/prowler-app/templates/worker/serviceaccount.yaml
@@ -0,0 +1,13 @@
+{{- if .Values.worker.serviceAccount.create -}}
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+ name: {{ include "prowler.worker.serviceAccountName" . }}
+ labels:
+ {{- include "prowler.labels" . | nindent 4 }}
+ {{- with .Values.worker.serviceAccount.annotations }}
+ annotations:
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
+automountServiceAccountToken: {{ .Values.worker.serviceAccount.automount }}
+{{- end }}
diff --git a/contrib/k8s/helm/prowler-app/templates/worker_beat/_helpers.tpl b/contrib/k8s/helm/prowler-app/templates/worker_beat/_helpers.tpl
new file mode 100644
index 0000000000..b9ce287667
--- /dev/null
+++ b/contrib/k8s/helm/prowler-app/templates/worker_beat/_helpers.tpl
@@ -0,0 +1,10 @@
+{{/*
+Create the name of the service account to use
+*/}}
+{{- define "prowler.worker_beat.serviceAccountName" -}}
+{{- if .Values.worker_beat.serviceAccount.create }}
+{{- default (printf "%s-%s" (include "prowler.fullname" .) "worker-beat") .Values.worker_beat.serviceAccount.name }}
+{{- else }}
+{{- default "default" .Values.worker_beat.serviceAccount.name }}
+{{- end }}
+{{- end }}
diff --git a/contrib/k8s/helm/prowler-app/templates/worker_beat/deployment.yaml b/contrib/k8s/helm/prowler-app/templates/worker_beat/deployment.yaml
new file mode 100644
index 0000000000..749ea946fd
--- /dev/null
+++ b/contrib/k8s/helm/prowler-app/templates/worker_beat/deployment.yaml
@@ -0,0 +1,99 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: {{ include "prowler.fullname" . }}-worker-beat
+ labels:
+ {{- include "prowler.labels" . | nindent 4 }}
+spec:
+ replicas: {{ .Values.worker_beat.replicaCount }}
+ selector:
+ matchLabels:
+ app.kubernetes.io/name: {{ include "prowler.fullname" . }}-worker-beat
+ template:
+ metadata:
+ annotations:
+ secret-hash: "{{ printf "%s%s%s" (.Files.Get "templates/api/configmap.yaml" | sha256sum) (.Files.Get "templates/api/secret-valkey.yaml" | sha256sum) | sha256sum }}"
+ {{- with .Values.worker.podAnnotations }}
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ labels:
+ {{- include "prowler.labels" . | nindent 8 }}
+ app.kubernetes.io/name: {{ include "prowler.fullname" . }}-worker-beat
+ {{- with .Values.worker_beat.podLabels }}
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ spec:
+ {{- with .Values.worker_beat.imagePullSecrets }}
+ imagePullSecrets:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ serviceAccountName: {{ include "prowler.worker_beat.serviceAccountName" . }}
+ {{- with .Values.worker_beat.podSecurityContext }}
+ securityContext:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ containers:
+ - name: worker-beat
+ {{- with .Values.worker_beat.securityContext }}
+ securityContext:
+ {{- toYaml . | nindent 12 }}
+ {{- end }}
+ image: "{{ .Values.worker_beat.image.repository }}:{{ .Values.worker_beat.image.tag | default .Chart.AppVersion }}"
+ imagePullPolicy: {{ .Values.worker_beat.image.pullPolicy }}
+ {{- with .Values.worker_beat.command }}
+ command:
+ {{- toYaml . | nindent 12 }}
+ {{- end }}
+ {{- with .Values.worker_beat.args }}
+ args:
+ {{- toYaml . | nindent 12 }}
+ {{- end }}
+ envFrom:
+ - configMapRef:
+ name: {{ include "prowler.fullname" . }}-api
+ {{- if .Values.valkey.enabled }}
+ - secretRef:
+ name: {{ include "prowler.fullname" . }}-api-valkey
+ {{- end }}
+ {{- with .Values.api.secrets }}
+ {{- range $index, $secret := . }}
+ - secretRef:
+ name: {{ $secret }}
+ {{- end }}
+ {{- end }}
+ env:
+ {{- include "prowler.django.env" . | nindent 12 }}
+ {{- include "prowler.postgresql.env" . | nindent 12 }}
+ {{- include "prowler.neo4j.env" . | nindent 12 }}
+ {{- with .Values.worker_beat.livenessProbe }}
+ livenessProbe:
+ {{- toYaml . | nindent 12 }}
+ {{- end }}
+ {{- with .Values.worker_beat.readinessProbe }}
+ readinessProbe:
+ {{- toYaml . | nindent 12 }}
+ {{- end }}
+ {{- with .Values.worker_beat.resources }}
+ resources:
+ {{- toYaml . | nindent 12 }}
+ {{- end }}
+ {{- with .Values.worker_beat.volumeMounts }}
+ volumeMounts:
+ {{- toYaml . | nindent 12 }}
+ {{- end }}
+ {{- with .Values.worker_beat.volumes }}
+ volumes:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- with .Values.worker_beat.nodeSelector }}
+ nodeSelector:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- with .Values.worker_beat.affinity }}
+ affinity:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- with .Values.worker_beat.tolerations }}
+ tolerations:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
diff --git a/contrib/k8s/helm/prowler-app/templates/worker_beat/serviceaccount.yaml b/contrib/k8s/helm/prowler-app/templates/worker_beat/serviceaccount.yaml
new file mode 100644
index 0000000000..9718686c2a
--- /dev/null
+++ b/contrib/k8s/helm/prowler-app/templates/worker_beat/serviceaccount.yaml
@@ -0,0 +1,13 @@
+{{- if .Values.worker_beat.serviceAccount.create -}}
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+ name: {{ include "prowler.worker_beat.serviceAccountName" . }}
+ labels:
+ {{- include "prowler.labels" . | nindent 4 }}
+ {{- with .Values.worker_beat.serviceAccount.annotations }}
+ annotations:
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
+automountServiceAccountToken: {{ .Values.worker_beat.serviceAccount.automount }}
+{{- end }}
diff --git a/contrib/k8s/helm/prowler-app/values.yaml b/contrib/k8s/helm/prowler-app/values.yaml
new file mode 100644
index 0000000000..46258351ad
--- /dev/null
+++ b/contrib/k8s/helm/prowler-app/values.yaml
@@ -0,0 +1,566 @@
+# This is to override the chart name.
+nameOverride: ""
+fullnameOverride: ""
+
+# Reference to the secret containing the API authentication secret.
+# Used to inject the environment variable for the API container.
+djangoTokenSigningKey:
+ secretKeyRef:
+ name: prowler-secret
+ key: DJANGO_TOKEN_SIGNING_KEY
+djangoTokenVerifyingKey:
+ secretKeyRef:
+ name: prowler-secret
+ key: DJANGO_TOKEN_VERIFYING_KEY
+djangoSecretsEncryptionKey:
+ secretKeyRef:
+ name: prowler-secret
+ key: DJANGO_SECRETS_ENCRYPTION_KEY
+
+ui:
+ # This will set the replicaset count more information can be found here: https://kubernetes.io/docs/concepts/workloads/controllers/replicaset/
+ replicaCount: 1
+
+ # This sets the container image more information can be found here: https://kubernetes.io/docs/concepts/containers/images/
+ image:
+ repository: prowlercloud/prowler-ui
+ # This sets the pull policy for images.
+ pullPolicy: IfNotPresent
+ # Overrides the image tag whose default is the chart appVersion.
+ tag: ""
+
+ # This is for the secrets for pulling an image from a private repository more information can be found here: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/
+ imagePullSecrets: []
+
+ # Reference to the secret containing the UI authentication secret.
+ # Used to inject the environment variable for the UI container.
+ # By default, expects a Secret named 'prowler-secret' with a key 'AUTH_SECRET'.
+ authSecret:
+ secretKeyRef:
+ name: prowler-secret
+ key: AUTH_SECRET
+
+ # Secret names to be used as env vars.
+ secrets: []
+ # - "prowler-ui-secret"
+
+ # This section builds out the service account more information can be found here: https://kubernetes.io/docs/concepts/security/service-accounts/
+ serviceAccount:
+ # Specifies whether a service account should be created
+ create: true
+ # Automatically mount a ServiceAccount's API credentials?
+ automount: true
+ # Annotations to add to the service account
+ annotations: {}
+ # The name of the service account to use.
+ # If not set and create is true, a name is generated using the fullname template
+ name: ""
+
+ # This is for setting Kubernetes Annotations to a Pod.
+ # For more information checkout: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/
+ podAnnotations: {}
+ # This is for setting Kubernetes Labels to a Pod.
+ # For more information checkout: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/
+ podLabels: {}
+
+ podSecurityContext: {}
+ # fsGroup: 2000
+
+ securityContext: {}
+ # capabilities:
+ # drop:
+ # - ALL
+ # readOnlyRootFilesystem: true
+ # runAsNonRoot: true
+ # runAsUser: 1000
+
+ # This is for setting up a service more information can be found here: https://kubernetes.io/docs/concepts/services-networking/service/
+ service:
+ # This sets the service type more information can be found here: https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types
+ type: ClusterIP
+ # This sets the ports more information can be found here: https://kubernetes.io/docs/concepts/services-networking/service/#field-spec-ports
+ port: 3000
+
+ # The URL of the UI. This is only set if ingress is disabled.
+ authUrl: ""
+
+ # This block is for setting up the ingress for more information can be found here: https://kubernetes.io/docs/concepts/services-networking/ingress/
+ ingress:
+ enabled: false
+ className: ""
+ annotations: {}
+ # kubernetes.io/ingress.class: nginx
+ # kubernetes.io/tls-acme: "true"
+ hosts:
+ - host: chart-example.local
+ paths:
+ - path: /
+ pathType: ImplementationSpecific
+ tls: []
+ # - secretName: chart-example-tls
+ # hosts:
+ # - chart-example.local
+
+ resources: {}
+ # We usually recommend not to specify default resources and to leave this as a conscious
+ # choice for the user. This also increases chances charts run on environments with little
+ # resources, such as Minikube. If you do want to specify resources, uncomment the following
+ # lines, adjust them as necessary, and remove the curly braces after 'resources:'.
+ # limits:
+ # memory: 128Mi
+ # requests:
+ # cpu: 100m
+ # memory: 128Mi
+
+ # This is to setup the liveness and readiness probes more information can be found here: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/
+ livenessProbe:
+ httpGet:
+ path: /
+ port: http
+ readinessProbe:
+ httpGet:
+ path: /
+ port: http
+
+ # This section is for setting up autoscaling more information can be found here: https://kubernetes.io/docs/concepts/workloads/autoscaling/
+ autoscaling:
+ enabled: false
+ minReplicas: 1
+ maxReplicas: 100
+ targetCPUUtilizationPercentage: 80
+ targetMemoryUtilizationPercentage: 80
+
+ # Additional volumes on the output Deployment definition.
+ volumes: []
+ # - name: foo
+ # secret:
+ # secretName: mysecret
+ # optional: false
+
+ # Additional volumeMounts on the output Deployment definition.
+ volumeMounts: []
+ # - name: foo
+ # mountPath: "/etc/foo"
+ # readOnly: true
+
+ nodeSelector: {}
+
+ tolerations: []
+
+ affinity: {}
+
+api:
+ # This will set the replicaset count more information can be found here: https://kubernetes.io/docs/concepts/workloads/controllers/replicaset/
+ replicaCount: 1
+
+ # This sets the container image more information can be found here: https://kubernetes.io/docs/concepts/containers/images/
+ image:
+ repository: prowlercloud/prowler-api
+ # This sets the pull policy for images.
+ pullPolicy: IfNotPresent
+ # Overrides the image tag whose default is the chart appVersion.
+ tag: ""
+
+ # Shared with celery-worker and celery-beat
+ djangoConfig:
+ # API scan settings
+ # The path to the directory where scan output should be stored
+ DJANGO_TMP_OUTPUT_DIRECTORY: "/tmp/prowler_api_output"
+ # The maximum number of findings to process in a single batch
+ DJANGO_FINDINGS_BATCH_SIZE: "1000"
+ # Django settings
+ DJANGO_ALLOWED_HOSTS: "*"
+ DJANGO_BIND_ADDRESS: "0.0.0.0"
+ DJANGO_PORT: "8080"
+ DJANGO_DEBUG: "False"
+ DJANGO_SETTINGS_MODULE: "config.django.production"
+ # Select one of [ndjson|human_readable]
+ DJANGO_LOGGING_FORMATTER: "ndjson"
+ # Select one of [DEBUG|INFO|WARNING|ERROR|CRITICAL]
+ # Applies to both Django and Celery Workers
+ DJANGO_LOGGING_LEVEL: "INFO"
+ # Defaults to the maximum available based on CPU cores if not set.
+ DJANGO_WORKERS: "4"
+ # Token lifetime is in minutes
+ DJANGO_ACCESS_TOKEN_LIFETIME: "30"
+ # Token lifetime is in minutes
+ DJANGO_REFRESH_TOKEN_LIFETIME: "1440"
+ DJANGO_CACHE_MAX_AGE: "3600"
+ DJANGO_STALE_WHILE_REVALIDATE: "60"
+ DJANGO_MANAGE_DB_PARTITIONS: "True"
+ DJANGO_BROKER_VISIBILITY_TIMEOUT: "86400"
+
+ # Secret names to be used as env vars for api, worker, and worker_beat.
+ secrets: []
+ # - "prowler-api-keys"
+
+ command:
+ - /home/prowler/docker-entrypoint.sh
+ args:
+ - prod
+
+ # This is for the secrets for pulling an image from a private repository more information can be found here: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/
+ imagePullSecrets: []
+
+ # This section builds out the service account more information can be found here: https://kubernetes.io/docs/concepts/security/service-accounts/
+ serviceAccount:
+ # Specifies whether a service account should be created
+ create: true
+ # Automatically mount a ServiceAccount's API credentials?
+ automount: true
+ # Annotations to add to the service account
+ annotations: {}
+ # The name of the service account to use.
+ # If not set and create is true, a name is generated using the fullname template
+ name: ""
+
+ # This is for setting Kubernetes Annotations to a Pod.
+ # For more information checkout: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/
+ podAnnotations: {}
+ # This is for setting Kubernetes Labels to a Pod.
+ # For more information checkout: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/
+ podLabels: {}
+
+ podSecurityContext: {}
+ # fsGroup: 2000
+
+ securityContext: {}
+ # capabilities:
+ # drop:
+ # - ALL
+ # readOnlyRootFilesystem: true
+ # runAsNonRoot: true
+ # runAsUser: 1000
+
+ # This is for setting up a service more information can be found here: https://kubernetes.io/docs/concepts/services-networking/service/
+ service:
+ # This sets the service type more information can be found here: https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types
+ type: ClusterIP
+ # This sets the ports more information can be found here: https://kubernetes.io/docs/concepts/services-networking/service/#field-spec-ports
+ port: 8080
+
+ # This block is for setting up the ingress for more information can be found here: https://kubernetes.io/docs/concepts/services-networking/ingress/
+ ingress:
+ enabled: false
+ className: ""
+ annotations: {}
+ # kubernetes.io/ingress.class: nginx
+ # kubernetes.io/tls-acme: "true"
+ hosts:
+ - host: chart-example.local
+ paths:
+ - path: /
+ pathType: ImplementationSpecific
+ tls: []
+ # - secretName: chart-example-tls
+ # hosts:
+ # - chart-example.local
+
+ resources: {}
+ # We usually recommend not to specify default resources and to leave this as a conscious
+ # choice for the user. This also increases chances charts run on environments with little
+ # resources, such as Minikube. If you do want to specify resources, uncomment the following
+ # lines, adjust them as necessary, and remove the curly braces after 'resources:'.
+ # limits:
+ # memory: 128Mi
+ # requests:
+ # cpu: 100m
+ # memory: 128Mi
+
+ # 3m30s to setup DB
+ # startupProbe:
+ # httpGet:
+ # path: /api/v1/docs
+ # port: http
+
+ # This is to setup the liveness and readiness probes more information can be found here: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/
+ livenessProbe:
+ failureThreshold: 10
+ httpGet:
+ path: /api/v1/docs
+ port: http
+ periodSeconds: 20
+ readinessProbe:
+ failureThreshold: 10
+ httpGet:
+ path: /api/v1/docs
+ port: http
+ periodSeconds: 20
+
+ # This section is for setting up autoscaling more information can be found here: https://kubernetes.io/docs/concepts/workloads/autoscaling/
+ autoscaling:
+ enabled: false
+ minReplicas: 1
+ maxReplicas: 100
+ targetCPUUtilizationPercentage: 80
+ targetMemoryUtilizationPercentage: 80
+
+ # Additional volumes on the output Deployment definition.
+ volumes: []
+ # - name: foo
+ # secret:
+ # secretName: mysecret
+ # optional: false
+
+ # Additional volumeMounts on the output Deployment definition.
+ volumeMounts: []
+ # - name: foo
+ # mountPath: "/etc/foo"
+ # readOnly: true
+
+ nodeSelector: {}
+
+ tolerations: []
+
+ affinity: {}
+
+worker:
+ # This will set the replicaset count more information can be found here: https://kubernetes.io/docs/concepts/workloads/controllers/replicaset/
+ replicaCount: 1
+
+ # This sets the container image more information can be found here: https://kubernetes.io/docs/concepts/containers/images/
+ image:
+ repository: prowlercloud/prowler-api
+ # This sets the pull policy for images.
+ pullPolicy: IfNotPresent
+ # Overrides the image tag whose default is the chart appVersion.
+ tag: ""
+
+ command:
+ - /home/prowler/docker-entrypoint.sh
+ args:
+ - worker
+
+ # This is for the secrets for pulling an image from a private repository more information can be found here: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/
+ imagePullSecrets: []
+
+ # This section builds out the service account more information can be found here: https://kubernetes.io/docs/concepts/security/service-accounts/
+ serviceAccount:
+ # Specifies whether a service account should be created
+ create: true
+ # Automatically mount a ServiceAccount's API credentials?
+ automount: true
+ # Annotations to add to the service account
+ annotations: {}
+ # The name of the service account to use.
+ # If not set and create is true, a name is generated using the fullname template
+ name: ""
+
+ # This is for setting Kubernetes Annotations to a Pod.
+ # For more information checkout: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/
+ podAnnotations: {}
+ # This is for setting Kubernetes Labels to a Pod.
+ # For more information checkout: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/
+ podLabels: {}
+
+ podSecurityContext: {}
+ # fsGroup: 2000
+
+ securityContext: {}
+ # capabilities:
+ # drop:
+ # - ALL
+ # readOnlyRootFilesystem: true
+ # runAsNonRoot: true
+ # runAsUser: 1000
+
+ resources: {}
+ # We usually recommend not to specify default resources and to leave this as a conscious
+ # choice for the user. This also increases chances charts run on environments with little
+ # resources, such as Minikube. If you do want to specify resources, uncomment the following
+ # lines, adjust them as necessary, and remove the curly braces after 'resources:'.
+ # limits:
+ # memory: 128Mi
+ # requests:
+ # cpu: 100m
+ # memory: 128Mi
+
+ # This is to setup the liveness and readiness probes more information can be found here: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/
+ livenessProbe: {}
+ readinessProbe: {}
+
+ # This section is for setting up autoscaling more information can be found here: https://kubernetes.io/docs/concepts/workloads/autoscaling/
+ autoscaling:
+ enabled: false
+ minReplicas: 1
+ maxReplicas: 10
+ targetCPUUtilizationPercentage: 80
+ targetMemoryUtilizationPercentage: 80
+
+ # Additional volumes on the output Deployment definition.
+ volumes: []
+ # - name: foo
+ # secret:
+ # secretName: mysecret
+ # optional: false
+
+ # Additional volumeMounts on the output Deployment definition.
+ volumeMounts: []
+ # - name: foo
+ # mountPath: "/etc/foo"
+ # readOnly: true
+
+ nodeSelector: {}
+
+ tolerations: []
+
+ affinity: {}
+
+ # KEDA ScaledObject configuration
+ keda:
+ # -- Set to `true` to enable KEDA for the worker pods
+ # Note: When both KEDA and HPA are enabled, the deployment will fail.
+ enabled: false
+ # -- The minimum number of replicas to use for the worker pods
+ minReplicas: 1
+ # -- The maximum number of replicas to use for the worker pods
+ maxReplicas: 2
+ # -- The polling interval in seconds for checking metrics
+ pollingInterval: 30
+ # -- The cooldown period in seconds for scaling
+ cooldownPeriod: 120
+ # -- The trigger type for scaling (cpu or memory)
+ triggerType: "postgresql"
+ # -- The target utilization percentage for the worker pods
+ value: "50"
+
+worker_beat:
+ # This will set the replicaset count more information can be found here: https://kubernetes.io/docs/concepts/workloads/controllers/replicaset/
+ replicaCount: 1
+
+ # This sets the container image more information can be found here: https://kubernetes.io/docs/concepts/containers/images/
+ image:
+ repository: prowlercloud/prowler-api
+ # This sets the pull policy for images.
+ pullPolicy: IfNotPresent
+ # Overrides the image tag whose default is the chart appVersion.
+ tag: ""
+
+ command:
+ - ../docker-entrypoint.sh
+ args:
+ - beat
+
+ # This is for the secrets for pulling an image from a private repository more information can be found here: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/
+ imagePullSecrets: []
+
+ # This section builds out the service account more information can be found here: https://kubernetes.io/docs/concepts/security/service-accounts/
+ serviceAccount:
+ # Specifies whether a service account should be created
+ create: true
+ # Automatically mount a ServiceAccount's API credentials?
+ automount: true
+ # Annotations to add to the service account
+ annotations: {}
+ # The name of the service account to use.
+ # If not set and create is true, a name is generated using the fullname template
+ name: ""
+
+ # This is for setting Kubernetes Annotations to a Pod.
+ # For more information checkout: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/
+ podAnnotations: {}
+ # This is for setting Kubernetes Labels to a Pod.
+ # For more information checkout: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/
+ podLabels: {}
+
+ podSecurityContext: {}
+ # fsGroup: 2000
+
+ securityContext: {}
+ # capabilities:
+ # drop:
+ # - ALL
+ # readOnlyRootFilesystem: true
+ # runAsNonRoot: true
+ # runAsUser: 1000
+
+ resources: {}
+ # We usually recommend not to specify default resources and to leave this as a conscious
+ # choice for the user. This also increases chances charts run on environments with little
+ # resources, such as Minikube. If you do want to specify resources, uncomment the following
+ # lines, adjust them as necessary, and remove the curly braces after 'resources:'.
+ # limits:
+ # memory: 128Mi
+ # requests:
+ # cpu: 100m
+ # memory: 128Mi
+
+ # This is to setup the liveness and readiness probes more information can be found here: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/
+ livenessProbe: {}
+ readinessProbe: {}
+
+ # Additional volumes on the output Deployment definition.
+ volumes: []
+ # - name: foo
+ # secret:
+ # secretName: mysecret
+ # optional: false
+
+ # Additional volumeMounts on the output Deployment definition.
+ volumeMounts: []
+ # - name: foo
+ # mountPath: "/etc/foo"
+ # readOnly: true
+
+ nodeSelector: {}
+
+ tolerations: []
+
+ affinity: {}
+
+postgresql:
+ # -- Enable PostgreSQL deployment (via Bitnami Helm Chart). If you want to use an external Postgres server (or a managed one), set this to false
+ # If enabled, it will create a Secret with the credentials.
+ # Otherwise, create a secret with the following and add it to the api deployment:
+ # - POSTGRES_HOST
+ # - POSTGRES_PORT
+ # - POSTGRES_ADMIN_USER - Existing user in charge of migrations, tables, permissions, RLS
+ # - POSTGRES_ADMIN_PASSWORD
+ # - POSTGRES_USER - Will be created by ADMIN_USER
+ # - POSTGRES_PASSWORD
+ # - POSTGRES_DB - Existing DB
+ enabled: true
+ image:
+ repository: "bitnami/postgresql"
+ auth:
+ database: prowler_db
+ username: prowler
+
+valkey:
+ # If enabled, it will create a Secret with the following.
+ # Otherwise, create a secret with
+ # - VALKEY_HOST
+ # - VALKEY_PORT
+ # - VALKEY_DB
+ enabled: true
+
+neo4j:
+ enabled: true
+
+ neo4j:
+ name: prowler-neo4j
+ edition: community
+
+ # The name of the secret containing the Neo4j password with the key NEO4J_PASSWORD
+ passwordFromSecret: prowler-secret
+
+ # Disable lookups during helm template rendering (required for ArgoCD)
+ disableLookups: true
+
+ volumes:
+ data:
+ mode: defaultStorageClass
+
+ services:
+ neo4j:
+ enabled: false
+
+ # Neo4j Configuration (yaml format)
+ config:
+ dbms_security_procedures_allowlist: "apoc.*"
+ dbms_security_procedures_unrestricted: "apoc.*"
+
+ apoc_config:
+ apoc.export.file.enabled: "true"
+ apoc.import.file.enabled: "true"
+ apoc.import.file.use_neo4j_config: "true"
diff --git a/dashboard/compliance/cis_3_1_oraclecloud.py b/dashboard/compliance/cis_3_1_oraclecloud.py
new file mode 100644
index 0000000000..7d51acf0f4
--- /dev/null
+++ b/dashboard/compliance/cis_3_1_oraclecloud.py
@@ -0,0 +1,41 @@
+import warnings
+
+from dashboard.common_methods import get_section_containers_cis
+
+warnings.filterwarnings("ignore")
+
+
+def get_table(data):
+ """
+ Generate CIS OCI Foundations Benchmark v3.1 compliance table.
+
+ Args:
+ data: DataFrame containing compliance check results with columns:
+ - REQUIREMENTS_ID: CIS requirement ID (e.g., "1.1", "2.1")
+ - REQUIREMENTS_DESCRIPTION: Description of the requirement
+ - REQUIREMENTS_ATTRIBUTES_SECTION: CIS section name
+ - CHECKID: Prowler check identifier
+ - STATUS: Check status (PASS/FAIL)
+ - REGION: OCI region
+ - ACCOUNTID: OCI tenancy OCID (renamed from TENANCYID)
+ - RESOURCEID: Resource OCID or identifier
+
+ Returns:
+ Section containers organized by CIS sections for dashboard display
+ """
+ aux = data[
+ [
+ "REQUIREMENTS_ID",
+ "REQUIREMENTS_DESCRIPTION",
+ "REQUIREMENTS_ATTRIBUTES_SECTION",
+ "CHECKID",
+ "STATUS",
+ "REGION",
+ "ACCOUNTID",
+ "RESOURCEID",
+ ]
+ ].copy()
+
+ return get_section_containers_cis(
+ aux, "REQUIREMENTS_ID", "REQUIREMENTS_ATTRIBUTES_SECTION"
+ )
diff --git a/dashboard/compliance/csa_ccm_4_0_alibabacloud.py b/dashboard/compliance/csa_ccm_4_0_alibabacloud.py
new file mode 100644
index 0000000000..346576729d
--- /dev/null
+++ b/dashboard/compliance/csa_ccm_4_0_alibabacloud.py
@@ -0,0 +1,31 @@
+import warnings
+
+from dashboard.common_methods import get_section_containers_kisa_ismsp
+
+warnings.filterwarnings("ignore")
+
+
+def get_table(data):
+ data["REQUIREMENTS_ID"] = (
+ data["REQUIREMENTS_ID"] + " - " + data["REQUIREMENTS_DESCRIPTION"]
+ )
+
+ data["REQUIREMENTS_ID"] = data["REQUIREMENTS_ID"].apply(
+ lambda x: x[:150] + "..." if len(str(x)) > 150 else x
+ )
+
+ aux = data[
+ [
+ "REQUIREMENTS_ID",
+ "REQUIREMENTS_ATTRIBUTES_SECTION",
+ "CHECKID",
+ "STATUS",
+ "REGION",
+ "ACCOUNTID",
+ "RESOURCEID",
+ ]
+ ].copy()
+
+ return get_section_containers_kisa_ismsp(
+ aux, "REQUIREMENTS_ATTRIBUTES_SECTION", "REQUIREMENTS_ID"
+ )
diff --git a/dashboard/compliance/csa_ccm_4_0_aws.py b/dashboard/compliance/csa_ccm_4_0_aws.py
new file mode 100644
index 0000000000..346576729d
--- /dev/null
+++ b/dashboard/compliance/csa_ccm_4_0_aws.py
@@ -0,0 +1,31 @@
+import warnings
+
+from dashboard.common_methods import get_section_containers_kisa_ismsp
+
+warnings.filterwarnings("ignore")
+
+
+def get_table(data):
+ data["REQUIREMENTS_ID"] = (
+ data["REQUIREMENTS_ID"] + " - " + data["REQUIREMENTS_DESCRIPTION"]
+ )
+
+ data["REQUIREMENTS_ID"] = data["REQUIREMENTS_ID"].apply(
+ lambda x: x[:150] + "..." if len(str(x)) > 150 else x
+ )
+
+ aux = data[
+ [
+ "REQUIREMENTS_ID",
+ "REQUIREMENTS_ATTRIBUTES_SECTION",
+ "CHECKID",
+ "STATUS",
+ "REGION",
+ "ACCOUNTID",
+ "RESOURCEID",
+ ]
+ ].copy()
+
+ return get_section_containers_kisa_ismsp(
+ aux, "REQUIREMENTS_ATTRIBUTES_SECTION", "REQUIREMENTS_ID"
+ )
diff --git a/dashboard/compliance/csa_ccm_4_0_azure.py b/dashboard/compliance/csa_ccm_4_0_azure.py
new file mode 100644
index 0000000000..346576729d
--- /dev/null
+++ b/dashboard/compliance/csa_ccm_4_0_azure.py
@@ -0,0 +1,31 @@
+import warnings
+
+from dashboard.common_methods import get_section_containers_kisa_ismsp
+
+warnings.filterwarnings("ignore")
+
+
+def get_table(data):
+ data["REQUIREMENTS_ID"] = (
+ data["REQUIREMENTS_ID"] + " - " + data["REQUIREMENTS_DESCRIPTION"]
+ )
+
+ data["REQUIREMENTS_ID"] = data["REQUIREMENTS_ID"].apply(
+ lambda x: x[:150] + "..." if len(str(x)) > 150 else x
+ )
+
+ aux = data[
+ [
+ "REQUIREMENTS_ID",
+ "REQUIREMENTS_ATTRIBUTES_SECTION",
+ "CHECKID",
+ "STATUS",
+ "REGION",
+ "ACCOUNTID",
+ "RESOURCEID",
+ ]
+ ].copy()
+
+ return get_section_containers_kisa_ismsp(
+ aux, "REQUIREMENTS_ATTRIBUTES_SECTION", "REQUIREMENTS_ID"
+ )
diff --git a/dashboard/compliance/csa_ccm_4_0_gcp.py b/dashboard/compliance/csa_ccm_4_0_gcp.py
new file mode 100644
index 0000000000..346576729d
--- /dev/null
+++ b/dashboard/compliance/csa_ccm_4_0_gcp.py
@@ -0,0 +1,31 @@
+import warnings
+
+from dashboard.common_methods import get_section_containers_kisa_ismsp
+
+warnings.filterwarnings("ignore")
+
+
+def get_table(data):
+ data["REQUIREMENTS_ID"] = (
+ data["REQUIREMENTS_ID"] + " - " + data["REQUIREMENTS_DESCRIPTION"]
+ )
+
+ data["REQUIREMENTS_ID"] = data["REQUIREMENTS_ID"].apply(
+ lambda x: x[:150] + "..." if len(str(x)) > 150 else x
+ )
+
+ aux = data[
+ [
+ "REQUIREMENTS_ID",
+ "REQUIREMENTS_ATTRIBUTES_SECTION",
+ "CHECKID",
+ "STATUS",
+ "REGION",
+ "ACCOUNTID",
+ "RESOURCEID",
+ ]
+ ].copy()
+
+ return get_section_containers_kisa_ismsp(
+ aux, "REQUIREMENTS_ATTRIBUTES_SECTION", "REQUIREMENTS_ID"
+ )
diff --git a/dashboard/compliance/csa_ccm_4_0_oraclecloud.py b/dashboard/compliance/csa_ccm_4_0_oraclecloud.py
new file mode 100644
index 0000000000..346576729d
--- /dev/null
+++ b/dashboard/compliance/csa_ccm_4_0_oraclecloud.py
@@ -0,0 +1,31 @@
+import warnings
+
+from dashboard.common_methods import get_section_containers_kisa_ismsp
+
+warnings.filterwarnings("ignore")
+
+
+def get_table(data):
+ data["REQUIREMENTS_ID"] = (
+ data["REQUIREMENTS_ID"] + " - " + data["REQUIREMENTS_DESCRIPTION"]
+ )
+
+ data["REQUIREMENTS_ID"] = data["REQUIREMENTS_ID"].apply(
+ lambda x: x[:150] + "..." if len(str(x)) > 150 else x
+ )
+
+ aux = data[
+ [
+ "REQUIREMENTS_ID",
+ "REQUIREMENTS_ATTRIBUTES_SECTION",
+ "CHECKID",
+ "STATUS",
+ "REGION",
+ "ACCOUNTID",
+ "RESOURCEID",
+ ]
+ ].copy()
+
+ return get_section_containers_kisa_ismsp(
+ aux, "REQUIREMENTS_ATTRIBUTES_SECTION", "REQUIREMENTS_ID"
+ )
diff --git a/dashboard/pages/compliance.py b/dashboard/pages/compliance.py
index f944f7f098..20395539e5 100644
--- a/dashboard/pages/compliance.py
+++ b/dashboard/pages/compliance.py
@@ -284,6 +284,11 @@ def display_data(
# Rename the column LOCATION to REGION for Alibaba Cloud
if "alibabacloud" in analytics_input:
data = data.rename(columns={"LOCATION": "REGION"})
+
+ # Rename the column TENANCYID to ACCOUNTID for Oracle Cloud
+ if "oraclecloud" in analytics_input:
+ data.rename(columns={"TENANCYID": "ACCOUNTID"}, inplace=True)
+
# Filter the chosen level of the CIS
if is_level_1:
data = data[data["REQUIREMENTS_ATTRIBUTES_PROFILE"].str.contains("Level 1")]
diff --git a/dashboard/pages/overview.py b/dashboard/pages/overview.py
index e2502c9aad..665aa8e195 100644
--- a/dashboard/pages/overview.py
+++ b/dashboard/pages/overview.py
@@ -259,6 +259,8 @@ else:
accounts.append(account + " - K8S")
if "alibabacloud" in list(data[data["ACCOUNT_UID"] == account]["PROVIDER"]):
accounts.append(account + " - ALIBABACLOUD")
+ if "oraclecloud" in list(data[data["ACCOUNT_UID"] == account]["PROVIDER"]):
+ accounts.append(account + " - OCI")
account_dropdown = create_account_dropdown(accounts)
@@ -306,6 +308,8 @@ else:
services.append(service + " - M365")
if "alibabacloud" in list(data[data["SERVICE_NAME"] == service]["PROVIDER"]):
services.append(service + " - ALIBABACLOUD")
+ if "oraclecloud" in list(data[data["SERVICE_NAME"] == service]["PROVIDER"]):
+ services.append(service + " - OCI")
services = ["All"] + services
services = [
@@ -767,6 +771,8 @@ def filter_data(
all_account_ids.append(account)
if "alibabacloud" in list(data[data["ACCOUNT_UID"] == account]["PROVIDER"]):
all_account_ids.append(account)
+ if "oraclecloud" in list(data[data["ACCOUNT_UID"] == account]["PROVIDER"]):
+ all_account_ids.append(account)
all_account_names = []
if "ACCOUNT_NAME" in filtered_data.columns:
@@ -793,6 +799,8 @@ def filter_data(
data[data["ACCOUNT_UID"] == item]["PROVIDER"]
):
cloud_accounts_options.append(item + " - ALIBABACLOUD")
+ if "oraclecloud" in list(data[data["ACCOUNT_UID"] == item]["PROVIDER"]):
+ cloud_accounts_options.append(item + " - OCI")
if "ACCOUNT_NAME" in filtered_data.columns:
if "azure" in list(data[data["ACCOUNT_NAME"] == item]["PROVIDER"]):
cloud_accounts_options.append(item + " - AZURE")
@@ -925,6 +933,10 @@ def filter_data(
filtered_data[filtered_data["SERVICE_NAME"] == item]["PROVIDER"]
):
service_filter_options.append(item + " - ALIBABACLOUD")
+ if "oraclecloud" in list(
+ filtered_data[filtered_data["SERVICE_NAME"] == item]["PROVIDER"]
+ ):
+ service_filter_options.append(item + " - OCI")
# Filter Service
if service_values == ["All"]:
@@ -1124,6 +1136,7 @@ def filter_data(
config={"displayModeBar": False},
)
table = dcc.Graph(figure=fig, config={"displayModeBar": False})
+ table_row_options = []
else:
# Status Pie Chart
diff --git a/docker-compose-dev.yml b/docker-compose-dev.yml
index b5de1af83f..9ab59f017d 100644
--- a/docker-compose-dev.yml
+++ b/docker-compose-dev.yml
@@ -144,6 +144,10 @@ services:
condition: service_healthy
neo4j:
condition: service_healthy
+ ulimits:
+ nofile:
+ soft: 65536
+ hard: 65536
entrypoint:
- "/home/prowler/docker-entrypoint.sh"
- "worker"
@@ -166,6 +170,10 @@ services:
condition: service_healthy
neo4j:
condition: service_healthy
+ ulimits:
+ nofile:
+ soft: 65536
+ hard: 65536
entrypoint:
- "../docker-entrypoint.sh"
- "beat"
diff --git a/docker-compose.yml b/docker-compose.yml
index 992a753ac0..798d1ecaba 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -117,6 +117,10 @@ services:
condition: service_healthy
postgres:
condition: service_healthy
+ ulimits:
+ nofile:
+ soft: 65536
+ hard: 65536
entrypoint:
- "/home/prowler/docker-entrypoint.sh"
- "worker"
@@ -131,6 +135,10 @@ services:
condition: service_healthy
postgres:
condition: service_healthy
+ ulimits:
+ nofile:
+ soft: 65536
+ hard: 65536
entrypoint:
- "../docker-entrypoint.sh"
- "beat"
diff --git a/docs/docs.json b/docs/docs.json
index 2f190ac36d..8305388369 100644
--- a/docs/docs.json
+++ b/docs/docs.json
@@ -255,6 +255,12 @@
"user-guide/providers/cloudflare/authentication"
]
},
+ {
+ "group": "Image",
+ "pages": [
+ "user-guide/providers/image/getting-started-image"
+ ]
+ },
{
"group": "LLM",
"pages": [
diff --git a/docs/images/prowler-app/saml/okta-app-assignments.png b/docs/images/prowler-app/saml/okta-app-assignments.png
new file mode 100644
index 0000000000..3881e646fc
Binary files /dev/null and b/docs/images/prowler-app/saml/okta-app-assignments.png differ
diff --git a/docs/images/prowler-app/saml/okta-user-profile-attributes.png b/docs/images/prowler-app/saml/okta-user-profile-attributes.png
new file mode 100644
index 0000000000..beb6781b2c
Binary files /dev/null and b/docs/images/prowler-app/saml/okta-user-profile-attributes.png differ
diff --git a/docs/images/prowler-app/saml/okta-user-profile-name.png b/docs/images/prowler-app/saml/okta-user-profile-name.png
new file mode 100644
index 0000000000..2a08d3437b
Binary files /dev/null and b/docs/images/prowler-app/saml/okta-user-profile-name.png differ
diff --git a/docs/introduction.mdx b/docs/introduction.mdx
index eee557b4fc..c354f2802d 100644
--- a/docs/introduction.mdx
+++ b/docs/introduction.mdx
@@ -36,7 +36,9 @@ The supported providers right now are:
| [Cloudflare](/user-guide/providers/cloudflare/getting-started-cloudflare) | Official | Accounts | CLI |
| [Infra as Code](/user-guide/providers/iac/getting-started-iac) | Official | Repositories | UI, API, CLI |
| [MongoDB Atlas](/user-guide/providers/mongodbatlas/getting-started-mongodbatlas) | Official | Organizations | UI, API, CLI |
+| [OpenStack](/user-guide/providers/openstack/getting-started-openstack) | Official | Projects | CLI |
| [LLM](/user-guide/providers/llm/getting-started-llm) | Official | Models | CLI |
+| [Image](/user-guide/providers/image/getting-started-image) | Official | Container Images | CLI |
| **NHN** | Unofficial | Tenants | CLI |
For more information about the checks and compliance of each provider visit [Prowler Hub](https://hub.prowler.com).
diff --git a/docs/troubleshooting.mdx b/docs/troubleshooting.mdx
index cd3da32946..a6a28c0ad6 100644
--- a/docs/troubleshooting.mdx
+++ b/docs/troubleshooting.mdx
@@ -49,15 +49,13 @@ AWS_PROFILE=prowler-profile
- If you are scanning multiple AWS accounts, you may need to add multiple profiles to your AWS config. Note that this workaround is mainly for local testing; for production or multi-account setups, follow the [CloudFormation Template guide](https://github.com/prowler-cloud/prowler/issues/7745) and ensure the correct IAM roles and permissions are set up in each account.
-### Scans complete but reports are missing or compliance data is empty (`Too many open files` error)
+### Scans Complete but Reports Are Missing or Compliance Data Is Empty (`Too many open files` Error)
-When running Prowler App via Docker Compose, you may encounter situations where scans complete successfully but reports are not available for download, compliance data shows as empty, or you see 404 errors when trying to access scan reports. Checking the `worker` container logs may reveal errors like `[Errno 24] Too many open files`.
+When running Prowler App via Docker Compose, scans may complete successfully but reports are not available for download, compliance data shows as empty, or 404 errors appear when trying to access scan reports. Checking the `worker` container logs may reveal errors like `[Errno 24] Too many open files`.
-This issue occurs because the default file descriptor limits in Docker containers are too low for Prowler's operations.
+This issue occurs because the default file descriptor limits in Docker containers are too low for Prowler's operations. The default `docker-compose.yml` already includes `ulimits` configuration with `nofile` set to `65536` for the `worker` and `worker-beat` services to prevent this issue.
-**Solution:**
-
-Add `ulimits` configuration to the `worker` and `worker-beat` services in your `docker-compose.yaml`:
+If a custom `docker-compose.yml` is being used or the default configuration has been modified, ensure the `ulimits` configuration is present in both the `worker` and `worker-beat` services:
```yaml
services:
@@ -76,17 +74,13 @@ services:
# ... rest of service configuration
```
-After making these changes, restart your Docker Compose stack:
+After making these changes, restart the Docker Compose stack:
```bash
docker compose down
docker compose up -d
```
-
-We are evaluating adding these values to the default `docker-compose.yml` to avoid this issue in future releases.
-
-
### API Container Fails to Start with JWT Key Permission Error
See [GitHub Issue #8897](https://github.com/prowler-cloud/prowler/issues/8897) for more details.
@@ -164,3 +158,44 @@ When these environment variables are set, the API will use them directly instead
A fix addressing this permission issue is being evaluated in [PR #9953](https://github.com/prowler-cloud/prowler/pull/9953).
+
+### SAML/OAuth ACS URL Incorrect When Running Behind a Proxy or Load Balancer
+
+See [GitHub Issue #9724](https://github.com/prowler-cloud/prowler/issues/9724) for more details.
+
+When running Prowler behind a reverse proxy (nginx, Traefik, etc.) or load balancer, the SAML ACS (Assertion Consumer Service) URL or OAuth callback URLs may be incorrectly generated using the internal container hostname (e.g., `http://prowler-api:8080/...`) instead of your external domain URL (e.g., `https://prowler.example.com/...`).
+
+**Root Cause:**
+
+Next.js environment variables prefixed with `NEXT_PUBLIC_` are **bundled at build time**, not runtime. The pre-built Docker images from Docker Hub (`prowlercloud/prowler-ui:stable`) are built with default internal URLs. Simply setting `NEXT_PUBLIC_API_BASE_URL` in your `.env` file or environment variables and restarting the container will **NOT** work because these values are already compiled into the JavaScript bundle.
+
+**Solution:**
+
+You must **rebuild** the UI Docker image with your external URL:
+
+```bash
+# Clone the repository (if you haven't already)
+git clone https://github.com/prowler-cloud/prowler.git
+cd prowler/ui
+
+# Build with your external URL as a build argument
+docker build \
+ --build-arg NEXT_PUBLIC_API_BASE_URL=https://prowler.example.com/api/v1 \
+ --build-arg NEXT_PUBLIC_API_DOCS_URL=https://prowler.example.com/api/v1/docs \
+ -t prowler-ui-custom:latest \
+ --target prod \
+ .
+```
+
+Then update your `docker-compose.yml` to use your custom image instead of the pre-built one:
+
+```yaml
+services:
+ ui:
+ image: prowler-ui-custom:latest # Use your custom-built image
+ # ... rest of configuration
+```
+
+
+The `NEXT_PUBLIC_` prefix is a Next.js convention that exposes environment variables to the browser. Since the browser bundle is compiled during `docker build`, these variables must be provided as build arguments, not runtime environment variables.
+
diff --git a/docs/user-guide/providers/github/authentication.mdx b/docs/user-guide/providers/github/authentication.mdx
index d76a0a1cb5..1ea4f49610 100644
--- a/docs/user-guide/providers/github/authentication.mdx
+++ b/docs/user-guide/providers/github/authentication.mdx
@@ -1,230 +1,447 @@
---
-title: 'GitHub Authentication in Prowler'
+title: "GitHub Authentication in Prowler"
---
-Prowler supports multiple methods to [authenticate with GitHub](https://docs.github.com/en/rest/authentication/authenticating-to-the-rest-api). These include:
+Prowler for GitHub offers multiple authentication types across Prowler Cloud and Prowler CLI.
-- [Personal Access Token (PAT)](/user-guide/providers/github/authentication#personal-access-token-pat)
-- [OAuth App Token](/user-guide/providers/github/authentication#oauth-app-token)
-- [GitHub App Credentials](/user-guide/providers/github/authentication#github-app-credentials)
+## Common Setup
-This flexibility enables scanning and analysis of GitHub accounts, including repositories, organizations, and applications, using the method that best suits the use case.
+### Authentication Methods Overview
-## Personal Access Token (PAT)
+Prowler offers three authentication methods. Fine-Grained Personal Access Tokens are recommended for most use cases.
+
+| Method | Best For | Key Benefit |
+|--------|----------|-------------|
+| [**Fine-Grained Personal Access Token**](#fine-grained-personal-access-token-recommended) | Individual users, quick setup | Simple, user-scoped access |
+| [**GitHub App**](#github-app-credentials) | Organizations, automation, CI/CD | Organization-scoped, no personal account dependency |
+| [**OAuth App Token**](#oauth-app-token) | Delegated user authorization | User-consented access flows |
+
+
+**Which should I choose?**
+
+- **Personal scanning or quick setup**: Use Fine-Grained PAT
+- **Organization-wide scanning or CI/CD pipelines**: Use GitHub App (recommended for production)
+- **Building apps with user authorization**: Use OAuth App
+
-Personal Access Tokens provide the simplest GitHub authentication method, but it can only access resources owned by a single user or organization.
-**Classic Tokens Deprecated**
+**Classic Personal Access Tokens**
-GitHub has deprecated Personal Access Tokens (classic) in favor of fine-grained Personal Access Tokens. We recommend using fine-grained tokens as they provide better security through more granular permissions and resource-specific access control.
+GitHub has deprecated classic Personal Access Tokens. Use Fine-Grained Tokens instead - they provide granular permission control and better security.
-#### **Option 1: Create a Fine-Grained Personal Access Token (Recommended)**
-1. **Navigate to GitHub Settings**
- - Open [GitHub](https://github.com) and sign in
- - Click the profile picture in the top right corner
- - Select "Settings" from the dropdown menu
+### Required Permissions
-2. **Access Developer Settings**
- - Scroll down the left sidebar
- - Click "Developer settings"
+Required permissions depend on the scan scope: user repositories, organization repositories, or both.
-3. **Generate Fine-Grained Token**
- - Click "Personal access tokens"
- - Select "Fine-grained tokens"
- - Click "Generate new token"
+#### Repository Permissions
-4. **Configure Token Settings**
- - **Token name**: Give your token a descriptive name (e.g., "Prowler Security Scanner")
- - **Expiration**: Set an appropriate expiration date (recommended: 90 days or less)
- - **Repository access**: Choose "All repositories" or "Only select repositories" based on your needs
+Required for scanning repository security settings:
-
- **Public repositories**
+| Permission | Access Level | Purpose | Checks Enabled |
+|------------|-------------|---------|----------------|
+| **Administration** | Read | Branch protection, security settings | All branch protection checks, secret scanning status |
+| **Contents** | Read | File existence checks | `repository_public_has_securitymd_file`, `repository_has_codeowners_file` |
+| **Metadata** | Read | Basic repository information | All checks (automatically granted) |
+| **Dependabot alerts** | Read | Dependency vulnerability scanning | `repository_dependency_scanning_enabled` |
- Even if you select 'Only select repositories', the token will have access to the public repositories that you own or are a member of.
+
+**Pull requests permission is optional.** It's only needed if you want to audit PR-specific settings beyond what branch protection provides.
+
-
-5. **Configure Token Permissions**
- To enable Prowler functionality, configure the following permissions:
+#### Organization Permissions
- - **Repository permissions:**
- - **Administration**: Read-only access
- - **Contents**: Read-only access
- - **Metadata**: Read-only access
- - **Pull requests**: Read-only access
+Required for scanning organization-level security settings:
- - **Organization permissions:**
- - **Administration**: Read-only access
- - **Members**: Read-only access
+
+**For Fine-Grained PATs:** Organization permissions only appear when the **Resource Owner** is set to an organization (not your personal account).
- - **Account permissions:**
- - **Email addresses**: Read-only access
+**For GitHub Apps:** Organization permissions are configured during app creation and apply to all organizations where the app is installed.
+
-6. **Copy and Store the Token**
- - Copy the generated token immediately (GitHub displays tokens only once)
- - Store tokens securely using environment variables
+| Permission | Access Level | Purpose | Checks Enabled |
+|------------|-------------|---------|----------------|
+| **Administration** | Read | Organization security policies | `organization_members_mfa_required`, `organization_repository_creation_limited`, `organization_default_repository_permission_strict` |
+| **Members** | Read | Member access reviews | Organization membership auditing |
-
+#### Account Permissions (Fine-Grained PAT only)
-#### **Option 2: Create a Classic Personal Access Token (Not Recommended)**
+| Permission | Access Level | Purpose |
+|------------|-------------|---------|
+| **Email addresses** | Read | User email verification |
+
+
+GitHub Apps don't have account-level permissions - they operate at the organization/repository level.
+
+
+### Permissions and Check Coverage
+
+With the **Read-only permissions** listed above, Prowler can run:
+
+| Check Category | Coverage | Notes |
+|----------------|----------|-------|
+| Branch protection checks (12 checks) | ✅ Full | Signed commits, status checks, PR reviews, etc. |
+| Repository security checks | ✅ Full | Secret scanning, Dependabot, SECURITY.md, CODEOWNERS |
+| Organization checks (3 checks) | ✅ Full | MFA, repo creation policies, default permissions |
+| Compliance frameworks | ✅ Full | CIS GitHub Benchmark and others |
+| Merge settings (`delete_branch_on_merge`) | ⚠️ MANUAL | Requires write permission (see below) |
+
+**Check that returns `MANUAL` status with Read-only permissions:**
+- `repository_branch_delete_on_merge_enabled`
-**Security Risk**
+**About Write Permissions**
-Classic tokens provide broad permissions that may exceed what Prowler actually needs. Use fine-grained tokens instead for better security.
+The `delete_branch_on_merge` setting is only returned by the GitHub API when the token has **Administration: Read and write** permission.
+
+**Granting Write permissions is not recommended under any circumstances:**
+- Token can modify repository settings
+- Token can change branch protection rules
+- Violates the principle of least privilege
+
+**Recommendation:** Accept `MANUAL` status for this single check rather than granting write access. This limitation applies equally to Fine-Grained PATs and GitHub Apps.
+
+
+### Step-by-Step Permission Assignment
+
+#### Fine-Grained Personal Access Token (Recommended for Individual Use)
+
+**Benefits of Fine-Grained Tokens**
+
+Fine-Grained Personal Access Tokens are ideal for:
+- **Individual users** scanning their own repositories
+- **Quick setup** without app registration overhead
+- **Temporary access** with mandatory expiration
+- **Repository-specific access** when you only need to scan certain repos
+
+**Create a Fine-Grained Token:**
+
+1. Navigate to **GitHub Settings** > **Developer settings**.
+
+2. Click **Personal access tokens** > **Fine-grained tokens** > **Generate new token**.
+
+3. Configure basic settings:
+ - **Token name**: Descriptive name (e.g., "Prowler Security Scanner")
+ - **Expiration**: 90 days or less (recommended)
+ - **Resource owner**:
+ - Personal account (for user repositories)
+ - Organization name (for organization scanning - requires admin approval)
+ - **Repository access**: "All repositories" (recommended)
+
+4. Configure **Repository permissions**:
+ - Administration: Read
+ - Contents: Read
+ - Metadata: Read (auto-selected)
+ - Dependabot alerts: Read
+
+5. Configure **Organization permissions** (only appears when Resource owner is an organization):
+ - Administration: Read
+ - Members: Read
+
+6. Configure **Account permissions**:
+ - Email addresses: Read (optional)
+
+7. Click **Generate token** and copy the token immediately.
+
+
+GitHub shows the token only once. Store it securely.
-1. **Navigate to GitHub Settings**
- - Open [GitHub](https://github.com) and sign in
- - Click the profile picture in the top right corner
- - Select "Settings" from the dropdown menu
-2. **Access Developer Settings**
- - Scroll down the left sidebar
- - Click "Developer settings"
+
-3. **Generate Classic Token**
- - Click "Personal access tokens"
- - Select "Tokens (classic)"
- - Click "Generate new token"
+#### OAuth App Token
-4. **Configure Token Permissions**
- To enable Prowler functionality, configure the following scopes:
- - `repo`: Full control of private repositories (includes `repo:status` and `repo:contents`)
- - `read:org`: Read organization and team membership
- - `read:user`: Read user profile data
- - `security_events`: Access security events (secret scanning and Dependabot alerts)
- - `read:enterprise`: Read enterprise data (if using GitHub Enterprise)
+**Recommended OAuth App Use Cases:**
-5. **Copy and Store the Token**
- - Copy the generated token immediately (GitHub displays tokens only once)
- - Store tokens securely using environment variables
+Use OAuth App Tokens when building applications that need delegated user permissions and explicit user authorization.
-## OAuth App Token
+**OAuth Scopes:**
-OAuth Apps enable applications to act on behalf of users with explicit consent.
+- `repo`: Full control of repositories
+- `read:org`: Read organization and team membership
+- `read:user`: Read user profile data
-### Create an OAuth App Token
+**Create an OAuth App:**
-1. **Navigate to Developer Settings**
- - Open GitHub Settings → Developer settings
- - Click "OAuth Apps"
+1. Navigate to **GitHub Settings** > **Developer settings** > **OAuth Apps**.
-2. **Register New Application**
- - Click "New OAuth App"
- - Complete the required fields:
- - **Application name**: Descriptive application name
- - **Homepage URL**: Application homepage
- - **Authorization callback URL**: User redirection URL after authorization
+2. Click **New OAuth App** and complete:
+ - Application name
+ - Homepage URL
+ - Authorization callback URL
-3. **Obtain Authorization Code**
- - Request authorization code (replace `{app_id}` with the application ID):
+3. Obtain authorization code:
```
https://github.com/login/oauth/authorize?client_id={app_id}
```
-4. **Exchange Code for Token**
- - Exchange authorization code for access token (replace `{app_id}`, `{secret}`, and `{code}`):
+4. Exchange authorization code for access token:
```
https://github.com/login/oauth/access_token?code={code}&client_id={app_id}&client_secret={secret}
```
-## GitHub App Credentials
-GitHub Apps provide the recommended integration method for accessing multiple repositories or organizations.
+#### GitHub App Credentials
-### Create a GitHub App
+
+**When to Use GitHub Apps**
-1. **Navigate to Developer Settings**
- - Open GitHub Settings → Developer settings
- - Click "GitHub Apps"
+GitHub Apps are ideal for:
+- **Organization-wide scanning** without tying access to a personal account
+- **CI/CD pipelines** where you need machine identity (not user-based)
+- **Multi-organization setups** with centralized app management
+- **Audit compliance** where you need to track app-level access separately from users
-2. **Create New GitHub App**
- - Click "New GitHub App"
- - Complete the required fields:
- - **GitHub App name**: Choose a unique, descriptive name (e.g., "Prowler Security Scanner")
- - **Homepage URL**: Enter your organization's website or the Prowler documentation URL (e.g., `https://prowler.com` or `https://docs.prowler.com`). This is just for reference and doesn't affect functionality.
- - **Webhook URL**: Leave blank or uncheck "Active" under Webhook. Prowler doesn't require webhooks since it performs on-demand scans rather than responding to GitHub events.
- - **Webhook secret**: Leave blank (not needed for Prowler)
- - **Permissions**: Configure in the next step (see below)
+GitHub Apps use the same permission model as Fine-Grained PATs - both provide full access to all Prowler checks.
+
-
- **About Homepage URL and Webhooks**
+**GitHub App Permissions:**
- The Homepage URL is purely informational and can be any valid URL - it's just displayed to users who view the app. Use your company website, your GitHub organization URL, or even `https://docs.prowler.com`.
+If a GitHub App is required:
- Webhooks are **not required** for Prowler. Since Prowler performs on-demand security scans when you run it (rather than automatically responding to GitHub events), you can safely disable webhooks or leave the URL blank.
-
+**Repository permissions:**
-3. **Configure Permissions**
- To enable Prowler functionality, configure these permissions:
- - **Repository permissions**:
- - Contents (Read)
- - Metadata (Read)
- - Pull requests (Read)
- - **Organization permissions**:
- - Members (Read)
- - Administration (Read)
- - **Account permissions**:
- - Email addresses (Read)
+| Permission | Access Level | Purpose | Checks Enabled |
+|------------|-------------|---------|----------------|
+| **Administration** | Read | Branch protection, security settings | All branch protection checks, `repository_secret_scanning_enabled` |
+| **Contents** | Read | File existence checks | `repository_public_has_securitymd_file`, `repository_has_codeowners_file` |
+| **Metadata** | Read | Basic repository information | All checks (automatically granted) |
+| **Dependabot alerts** | Read | Dependency vulnerability scanning | `repository_dependency_scanning_enabled` |
-4. **Where can this GitHub App be installed?**
- - Select "Any account" to be able to install the GitHub App in any organization.
+**Organization permissions:**
-5. **Generate Private Key**
- - Scroll to the "Private keys" section after app creation
- - Click "Generate a private key"
- - Download the `.pem` file and store securely
+| Permission | Access Level | Purpose | Checks Enabled |
+|------------|-------------|---------|----------------|
+| **Administration** | Read | Organization security policies | `organization_members_mfa_required`, `organization_repository_creation_limited`, `organization_default_repository_permission_strict` |
+| **Members** | Read | Member access reviews | Organization membership auditing |
-5. **Record App ID**
- - Locate the App ID at the top of the GitHub App settings page
+**Create a GitHub App:**
-### Install the GitHub App
+1. Navigate to **GitHub Settings** > **Developer settings** > **GitHub Apps**.
-1. **Install Application**
- - Navigate to GitHub App settings
- - Click "Install App" in the left sidebar
- - Select the target account/organization
- - Choose specific repositories or select "All repositories"
+2. Click **New GitHub App** and complete:
+ - **GitHub App name**: Descriptive name (e.g., "Prowler Security Scanner")
+ - **Homepage URL**: Your organization's URL or Prowler documentation
+ - **Webhook**: Uncheck "Active" (Prowler doesn't need webhooks)
-## Best Practices
+3. Configure **Repository permissions** (see table above):
+ - Administration: Read
+ - Contents: Read
+ - Metadata: Read (auto-selected)
+ - Dependabot alerts: Read
-### Security Considerations
+4. Configure **Organization permissions** (see table above):
+ - Administration: Read
+ - Members: Read
-Implement the following security measures:
+5. Under **Where can this GitHub App be installed?**, select:
+ - "Only on this account" for single-organization use
+ - "Any account" if you need to install across multiple organizations
-- **Secure Credential Storage**: Store credentials using environment variables instead of hardcoding tokens
-- **Secrets Management**: Use dedicated secrets management systems in production environments
-- **Regular Token Rotation**: Rotate tokens and keys regularly
-- **Least Privilege Principle**: Grant only minimum required permissions
-- **Permission Auditing**: Review and audit permissions regularly
-- **Token Expiration**: Set appropriate expiration times for tokens
-- **Usage Monitoring**: Monitor token usage and revoke unused tokens
+6. Click **Create GitHub App**.
-### Authentication Method Selection
+7. On the app settings page:
+ - Record the **App ID** (displayed at the top)
+ - Click **Generate a private key** and download the `.pem` file
-Choose the appropriate method based on use case:
+8. Install the GitHub App:
+ - Click **Install App** in the left sidebar
+ - Select target account/organization
+ - Choose "All repositories" or select specific repositories
+ - Click **Install**
-- **Personal Access Token**: Individual use, testing, or simple automation
-- **OAuth App Token**: Applications requiring user consent and delegation
-- **GitHub App**: Production integrations, especially for organizations
+
+**Private Key Security**
-## Troubleshooting Common Issues
+Store the `.pem` private key securely. Anyone with this key can authenticate as your GitHub App. Never commit it to version control.
+
-### Insufficient Permissions
-- Verify token/app has necessary scopes/permissions
-- Check organization restrictions on third-party applications
+---
-### Token Expiration
-- Confirm token has not expired
-- Verify fine-grained tokens have correct resource access
+## Prowler Cloud Authentication
+
+For step-by-step setup instructions for Prowler Cloud, see the [Getting Started Guide](/user-guide/providers/github/getting-started-github#prowler-cloudapp).
+
+### Using Personal Access Token
+
+1. In Prowler Cloud, navigate to **Configuration** > **Cloud Providers** > **Add Cloud Provider** > **GitHub**.
+
+2. Enter your GitHub Account ID (username or organization name).
+
+3. Select **Personal Access Token** as the authentication method.
+
+4. Enter your Fine-Grained Personal Access Token.
+
+5. Click **Verify** to test the connection, then **Save**.
+
+### Using OAuth App Token
+
+1. Follow the same steps as Personal Access Token.
+
+2. Select **OAuth App Token** as the authentication method.
+
+3. Enter your OAuth App Token.
+
+### Using GitHub App
+
+1. Follow the same steps as Personal Access Token.
+
+2. Select **GitHub App** as the authentication method.
+
+3. Enter your GitHub App ID and upload the private key (`.pem` file).
+
+For complete step-by-step instructions, see the [Getting Started Guide](/user-guide/providers/github/getting-started-github#prowler-cloudapp).
+
+---
+
+## Prowler CLI Authentication
+
+### Authentication Methods
+
+Prowler CLI automatically detects credentials using environment variables in this order:
+
+1. `GITHUB_PERSONAL_ACCESS_TOKEN`
+2. `GITHUB_OAUTH_APP_TOKEN`
+3. `GITHUB_APP_ID` and `GITHUB_APP_KEY`
+
+### Using Environment Variables (Recommended)
+
+```bash
+# Personal Access Token (Recommended)
+export GITHUB_PERSONAL_ACCESS_TOKEN="ghp_xxxxxxxxxxxx"
+prowler github
+
+# OAuth App Token
+export GITHUB_OAUTH_APP_TOKEN="oauth_token_here"
+prowler github
+
+# GitHub App
+export GITHUB_APP_ID="123456"
+export GITHUB_APP_KEY="$(cat /path/to/private-key.pem)"
+prowler github
+```
+
+### Using CLI Flags
+
+```bash
+# Personal Access Token
+prowler github --personal-access-token ghp_xxxxxxxxxxxx
+
+# OAuth App Token
+prowler github --oauth-app-token oauth_token_here
+
+# GitHub App
+prowler github --github-app-id 123456 --github-app-key-path /path/to/private-key.pem
+```
+
+### Scan Scope
+
+
+**Understanding Scan Scope**
+
+What Prowler scans depends on the invocation method:
+
+| Command | What Gets Scanned | Organization Checks? |
+|---------|------------------|---------------------|
+| `prowler github` | All accessible repositories | No |
+| `prowler github --repository owner/repo` | Single repository | No |
+| `prowler github --organization org-name` | Organization repos + settings | Yes |
+
+**Key Point:** Scanning user repositories does NOT include organization-level checks. To audit organization MFA, security policies, etc., you must use `--organization`.
+
+
+
+**Scan user repositories:**
+
+```bash
+prowler github
+prowler github --repository username/my-repo
+```
+
+**Scan organizations:**
+
+```bash
+prowler github --organization org-name
+prowler github --organization org1 --organization org2
+```
+
+**Filter scans:**
+
+```bash
+prowler github --severity critical
+prowler github --checks repository_default_branch_protection_enabled
+prowler github --compliance cis_1.0_github
+```
+
+For complete step-by-step instructions, see the [Getting Started Guide](/user-guide/providers/github/getting-started-github#prowler-cli).
+
+---
+
+## Troubleshooting
+
+### "Insufficient Permissions" Errors
+
+**Symptom:** Checks fail or return `MANUAL` status.
+
+**Solutions:**
+1. Verify token has all required permissions
+2. For organization scans, ensure organization approved the Fine-Grained Token
+3. For merge settings checks, accept `MANUAL` status (Write permission not recommended)
+
+### "No Organizations Found"
+
+**Symptom:** Prowler doesn't find organizations even though you're a member.
+
+**Cause:** Fine-Grained Token's Resource Owner is set to personal account.
+
+**Solution:** Create a new token with Resource Owner set to the organization and get it approved by an admin.
+
+### Organization Checks Return `MANUAL`
+
+**Symptom:** Checks like `organization_members_mfa_required` return `MANUAL`.
+
+**Cause:** Token lacks `Organization → Administration: Read` permission.
+
+**Solutions:**
+1. Edit token and grant `Organization → Administration: Read`
+2. Ensure token's **Resource owner** is the organization (not personal account)
+3. Get organization admin approval
+
+### Token Not Showing Organization Permissions
+
+**Symptom:** Can't find Organization permissions section when creating token.
+
+**Cause:** **Resource owner** is set to personal account.
+
+**Solution:** Change **Resource owner** dropdown to the organization name. Organization permissions section will appear.
### Rate Limiting
-- GitHub implements API call rate limits
-- Consider GitHub Apps for higher rate limits
-### Organization Settings
-- Some organizations restrict third-party applications
-- Contact organization administrator if access is denied
+**Symptom:** "API rate limit exceeded" errors.
+
+**Solutions:**
+- Scan during off-peak hours
+- Use `--repository` to scan specific repos instead of all
+- Implement delays between scans
+
+### Token Expired or Revoked
+
+**Symptom:** Authentication fails with valid-looking token.
+
+**Solutions:**
+1. Check token expiration date in GitHub settings
+2. Verify token wasn't revoked
+3. For Fine-Grained Tokens, check if organization approval was revoked
+4. Generate a new token
+
+---
+
+## Additional Resources
+
+- [GitHub REST API Authentication](https://docs.github.com/en/rest/authentication)
+- [Fine-Grained Personal Access Tokens](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens#creating-a-fine-grained-personal-access-token)
+- [GitHub Apps Documentation](https://docs.github.com/en/apps)
+- [GitHub API Rate Limits](https://docs.github.com/en/rest/overview/rate-limits-for-the-rest-api)
+- [Getting Started Guide](/user-guide/providers/github/getting-started-github)
diff --git a/docs/user-guide/providers/github/getting-started-github.mdx b/docs/user-guide/providers/github/getting-started-github.mdx
index 41d472df61..b074262680 100644
--- a/docs/user-guide/providers/github/getting-started-github.mdx
+++ b/docs/user-guide/providers/github/getting-started-github.mdx
@@ -2,91 +2,441 @@
title: 'Getting Started with GitHub'
---
-## Prowler App
+This guide covers setting up GitHub security scanning with Prowler. Choose a preferred interface below:
+
+
+**Understanding GitHub Scan Scope**
+
+Prowler can scan either:
+- **User Repositories**: All repositories owned by or accessible to a specific GitHub user
+- **Organizations**: Repositories and organization-level settings
+
+**Important**: Scanning user repositories does NOT include organization-level checks (MFA requirements, security policies, etc.). To scan organizations, you must explicitly configure them.
+
+
+
+
+
+ Web-based interface with centralized management
+
+
+ Command-line interface for local or automated scans
+
+
+
+---
+
+## Prowler Cloud/App
> Walkthrough video onboarding a GitHub Account using GitHub App.
+### Prerequisites
+
+Before adding GitHub to Prowler Cloud/App, ensure you have:
+
+1. **GitHub Account Access**
+ - Personal GitHub account, OR
+ - Admin access to a GitHub organization
+
+2. **Authentication Credentials**
+ - Choose one method (see [Authentication Guide](/user-guide/providers/github/authentication)):
+ - **Fine-Grained Personal Access Token** (Recommended)
+ - OAuth App Token
+ - GitHub App Credentials (Not Recommended - limited data access)
+
### Step 1: Access Prowler Cloud/App
1. Navigate to [Prowler Cloud](https://cloud.prowler.com/) or launch [Prowler App](/user-guide/tutorials/prowler-app)
-2. Go to "Configuration" > "Cloud Providers"
+2. Go to **Configuration** → **Cloud Providers**

-3. Click "Add Cloud Provider"
+3. Click **Add Cloud Provider**

-4. Select "GitHub"
+4. Select **GitHub**

-5. Add the GitHub Account ID (username or organization name) and an optional alias, then click "Next"
+### Step 2: Configure GitHub Account
+
+5. Add the **GitHub Account ID** and an optional alias:
+ - **Account ID**: Your GitHub username (e.g., `username`) or organization name (e.g., `org-name`)
+ - **Alias** (optional): Friendly name for this connection (e.g., `My Personal Repos` or `Prowler Org`)

-### Step 2: Choose the preferred authentication method
+6. Click **Next**
-6. Choose the preferred authentication method:
+### Step 3: Choose Authentication Method
+
+
+**Recommended: Fine-Grained Personal Access Token**
+
+**Fine-Grained Personal Access Tokens** are strongly recommended because they provide:
+- Best data access for comprehensive security scanning
+- Granular permission control
+- Resource-specific access
+
+**GitHub Apps are not recommended** — they provide the most limited access to GitHub data for security scanning purposes.
+
+
+7. Select your preferred authentication method:

-7. Configure the authentication method:
-
-
+

- For more details on how to create a Personal Access Token, see [Authentication > Personal Access Token](/user-guide/providers/github/authentication#personal-access-token-pat).
+ **Recommended method** - provides the best data access for security scanning.
+
+ 1. Enter your Fine-Grained Personal Access Token
+ 2. Click **Verify** to test the connection
+ 3. Click **Save**
+
+ **Don't have a token yet?** See [How to create a Personal Access Token](/user-guide/providers/github/authentication#create-a-fine-grained-personal-access-token)
+

- For more details on how to create an OAuth App Token, see [Authentication > OAuth App Token](/user-guide/providers/github/authentication#oauth-app-token).
+ For applications requiring user consent and delegated permissions.
+
+ 1. Enter your OAuth App Token
+ 2. Click **Verify** to test the connection
+ 3. Click **Save**
+
+ **Don't have an OAuth token?** See [How to create an OAuth App Token](/user-guide/providers/github/authentication#oauth-app-token)
-
+
+

- For more details on how to create a GitHub App, see [Authentication > GitHub App](/user-guide/providers/github/authentication#github-app-credentials).
+
+ **Not recommended** - most limited data access. Use only if required by organization policy.
+
+
+ 1. Enter your GitHub App ID
+ 2. Upload or paste your Private Key (`.pem` file)
+ 3. Click **Verify** to test the connection
+ 4. Click **Save**
+
+ **Don't have a GitHub App?** See [How to create a GitHub App](/user-guide/providers/github/authentication#github-app-credentials)
+
+
+8. Click **Start Scan** to begin your first security assessment
+
+### Step 5: View Results
+
+Once the scan completes, you can:
+- View security findings in the dashboard
+- Export results in multiple formats (JSON, CSV, HTML)
+- Set up continuous scanning schedules
+- Configure alerts for critical findings
+
+---
+
## Prowler CLI
-### Automatic Login Method Detection
+### Prerequisites
-If no login method is explicitly provided, Prowler will automatically attempt to authenticate using environment variables in the following order of precedence:
+Before running Prowler CLI for GitHub, ensure you have:
+
+1. **Prowler Installed**
+ ```bash
+ # Install via pip
+ pip install prowler
+
+ # Or via poetry
+ poetry install
+ ```
+
+2. **Authentication Credentials**
+ - Choose one method (see [Authentication Guide](/user-guide/providers/github/authentication)):
+ - **Fine-Grained Personal Access Token** (Recommended)
+ - OAuth App Token
+ - GitHub App Credentials (Not Recommended)
+
+### Authentication Setup
+
+Prowler CLI automatically detects authentication credentials using environment variables in this order:
1. `GITHUB_PERSONAL_ACCESS_TOKEN`
2. `GITHUB_OAUTH_APP_TOKEN`
-3. `GITHUB_APP_ID` and `GITHUB_APP_KEY` (where the key is the content of the private key file)
+3. `GITHUB_APP_ID` and `GITHUB_APP_KEY`
+
+
+
+```bash
+# Personal Access Token (Recommended)
+export GITHUB_PERSONAL_ACCESS_TOKEN="ghp_xxxxxxxxxxxx"
+
+# OAuth App Token
+export GITHUB_OAUTH_APP_TOKEN="oauth_token_here"
+
+# GitHub App
+export GITHUB_APP_ID="123456"
+export GITHUB_APP_KEY="$(cat /path/to/private-key.pem)"
+```
+
+Then run Prowler without additional flags:
+```bash
+prowler github
+```
+
+
+
+```bash
+# Personal Access Token
+prowler github --personal-access-token ghp_xxxxxxxxxxxx
+
+# OAuth App Token
+prowler github --oauth-app-token oauth_token_here
+
+# GitHub App
+prowler github --github-app-id 123456 --github-app-key-path /path/to/private-key.pem
+```
+
+
+
+**Don't have credentials yet?** See the [Authentication Guide](/user-guide/providers/github/authentication) for step-by-step instructions.
+
+### Scan Scope: Understanding What Gets Scanned
+
+
+**Distinguishing User Scans from Organization Scans**
+
+The scan scope depends entirely on the Prowler CLI invocation method:
+
+| Command | What Gets Scanned | Organization Checks Included? |
+|---------|------------------|-------------------------------|
+| `prowler github` | All repositories the token has access to | No |
+| `prowler github --repository owner/repo` | Single specified repository | No |
+| `prowler github --organization org-name` | Organization repos + org settings | Yes |
+| `prowler github --organization org-name --repository owner/repo` | Organization + single repository | Yes |
+
+**Key Points:**
+- Scanning **user repositories** does NOT run organization-level checks
+- To audit organization MFA, security policies, etc., the `--organization` flag is required
+- Members of multiple organizations should specify each one explicitly
+
+
+
+### Scanning User Repositories
+
+Scan repositories owned by your user account:
+
+```bash
+# Scan all repositories accessible to your token
+prowler github
+
+# Scan a specific repository
+prowler github --repository username/my-repo
+
+# Scan multiple specific repositories
+prowler github --repository username/repo1 --repository username/repo2
+```
+
+**What gets scanned:**
+- Repository security settings
+- Branch protection rules
+- Secret scanning configuration
+- Dependabot settings
+- Organization-level policies (not included)
+
+### Scanning Organizations
+
+Scan organization repositories and organization-level security settings:
+
+```bash
+# Scan a single organization
+prowler github --organization prowler-cloud
+
+# Scan multiple organizations
+prowler github --organization org1 --organization org2
+
+# Scan organization and specific repositories within it
+prowler github --organization my-org --repository my-org/critical-repo
+```
+
+**What gets scanned:**
+- All organization repositories
+- Repository security settings
+- Organization MFA requirements
+- Organization security policies
+- Member access and permissions
+
+### Scan Scoping
+
+Scan scoping controls which repositories and organizations Prowler includes in a security assessment. By default, Prowler scans all repositories accessible to the authenticated user or organization. To limit the scan to specific repositories or organizations, use the following flags.
+
+#### Scanning Specific Repositories
+
+To restrict the scan to one or more repositories, use the `--repository` flag followed by the repository name(s) in `owner/repo-name` format:
+
+```console
+prowler github --repository owner/repo-name
+```
+
+To scan multiple repositories, specify them as space-separated arguments:
+
+```console
+prowler github --repository owner/repo-name-1 owner/repo-name-2
+```
+
+#### Scanning Specific Organizations
+
+To restrict the scan to one or more organizations or user accounts, use the `--organization` flag:
+
+```console
+prowler github --organization my-organization
+```
+
+To scan multiple organizations, specify them as space-separated arguments:
+
+```console
+prowler github --organization org-1 org-2
+```
+
+#### Scanning Specific Repositories Within an Organization
+
+To scan specific repositories within an organization, combine the `--organization` and `--repository` flags. The `--organization` flag qualifies unqualified repository names automatically:
+
+```console
+prowler github --organization my-organization --repository my-repo
+```
+
+This scans only `my-organization/my-repo`. Fully qualified repository names (`owner/repo-name`) are also supported alongside `--organization`:
+
+```console
+prowler github --organization my-org --repository my-repo other-owner/other-repo
+```
+
+In this case, `my-repo` is qualified as `my-org/my-repo`, while `other-owner/other-repo` is used as-is.
-Ensure the corresponding environment variables are set up before running Prowler for automatic detection when not specifying the login method.
-
+The `--repository` and `--organization` flags can be combined with any authentication method.
-For more details on how to set up authentication with GitHub, see [Authentication > GitHub](/user-guide/providers/github/authentication).
-### Personal Access Token (PAT)
+### Filtering Scans
-Use this method by providing your personal access token directly.
+Customize your scan scope with these options:
-```console
-prowler github --personal-access-token pat
+```bash
+# Run only critical severity checks
+prowler github --severity critical
+
+# Run specific checks
+prowler github --checks repository_default_branch_protection_enabled,organization_members_mfa_required
+
+# Exclude specific checks
+prowler github --excluded-checks repository_archived
+
+# Scan with specific compliance framework
+prowler github --compliance cis_1.0_github
+
+# Output results in specific format
+prowler github --output-formats json,csv,html
```
-### OAuth App Token
+### Example Workflows
-Authenticate using an OAuth app token.
+
+
+```bash
+# Scan your personal repositories for critical issues
+export GITHUB_PERSONAL_ACCESS_TOKEN="ghp_xxxx"
+prowler github --severity critical high
+```
+
-```console
-prowler github --oauth-app-token oauth_token
+
+```bash
+# Full organization scan with CIS compliance
+export GITHUB_PERSONAL_ACCESS_TOKEN="ghp_xxxx"
+prowler github \
+ --organization prowler-cloud \
+ --compliance cis_1.0_github \
+ --output-formats json,html
+```
+
+
+
+```bash
+# Scan specific repository in CI pipeline
+prowler github \
+ --personal-access-token "$GITHUB_TOKEN" \
+ --repository "$GITHUB_REPOSITORY" \
+ --severity critical \
+ --output-formats json
+
+# Exit with non-zero if critical findings
+if grep -q '"Status": "FAIL".*"Severity": "critical"' prowler-output*.json; then
+ echo "Critical security issues found!"
+ exit 1
+fi
+```
+
+
+
+```bash
+# Scan multiple organizations you're part of
+export GITHUB_PERSONAL_ACCESS_TOKEN="ghp_xxxx"
+prowler github \
+ --organization org1 \
+ --organization org2 \
+ --organization org3 \
+ --output-formats csv
+```
+
+
+
+### Viewing Prowler CLI Scan Results
+
+Prowler CLI generates results in multiple formats:
+
+```bash
+# Results are saved in ./output/ directory by default
+ls output/
+
+# View HTML report in browser
+open output/prowler-output-*.html
+
+# Parse JSON results with jq
+cat output/prowler-output-*.json | jq '.findings[] | select(.Status=="FAIL")'
+
+# Import CSV into spreadsheet
+open output/prowler-output-*.csv
```
-### GitHub App Credentials
-Use GitHub App credentials by specifying the App ID and the private key path.
+---
-```console
-prowler github --github-app-id app_id --github-app-key-path app_key_path
-```
+## Next Steps
+
+
+
+ Detailed permissions and token creation
+
+
+ Browse all GitHub security checks
+
+
+ CIS, NIST, and other frameworks
+
+
+ Common issues and solutions
+
+
+
+## Additional Resources
+
+- [GitHub REST API Documentation](https://docs.github.com/en/rest)
+- [Fine-Grained Personal Access Tokens](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens#creating-a-fine-grained-personal-access-token)
+- [GitHub Security Best Practices](https://docs.github.com/en/code-security)
+- [Prowler CLI Reference](/getting-started/basic-usage/prowler-cli)
diff --git a/docs/user-guide/providers/image/getting-started-image.mdx b/docs/user-guide/providers/image/getting-started-image.mdx
new file mode 100644
index 0000000000..4fe509c2af
--- /dev/null
+++ b/docs/user-guide/providers/image/getting-started-image.mdx
@@ -0,0 +1,197 @@
+---
+title: "Getting Started with the Image Provider"
+---
+
+import { VersionBadge } from "/snippets/version-badge.mdx"
+
+Prowler's Image provider enables comprehensive container image security scanning by integrating with [Trivy](https://trivy.dev/). This provider detects vulnerabilities, exposed secrets, and misconfigurations in container images, converting Trivy findings into Prowler's standard reporting format for unified security assessment.
+
+## How It Works
+
+* **Trivy integration:** Prowler leverages [Trivy](https://trivy.dev/) to scan container images for vulnerabilities, secrets, misconfigurations, and license issues.
+* **Trivy required:** Trivy must be installed and available in the system PATH before running any scan.
+* **Authentication:** No registry authentication is required for public images. For private registries, configure Docker credentials via `docker login` before scanning.
+* **Output formats:** Results are output in the same formats as other Prowler providers (CSV, JSON, HTML, etc.).
+
+## Prowler CLI
+
+
+
+
+The Image provider is currently available in Prowler CLI only.
+
+
+### Install Trivy
+
+Install Trivy using one of the following methods:
+
+
+
+ ```bash
+ brew install trivy
+ ```
+
+
+ ```bash
+ sudo apt-get install trivy
+ ```
+
+
+ ```bash
+ curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh -s -- -b /usr/local/bin
+ ```
+
+
+
+For additional installation methods, see the [Trivy installation guide](https://trivy.dev/latest/getting-started/installation/).
+
+
+### Supported Scanners
+
+Prowler CLI supports the following scanners:
+
+* [Vulnerability](https://trivy.dev/docs/latest/guide/scanner/vulnerability/)
+* [Secret](https://trivy.dev/docs/latest/guide/scanner/secret/)
+* [Misconfiguration](https://trivy.dev/docs/latest/guide/scanner/misconfiguration/)
+* [License](https://trivy.dev/docs/latest/guide/scanner/license/)
+
+By default, only vulnerability and secret scanners run during a scan. To specify which scanners to use, refer to the [Specify Scanners](#specify-scanners) section below.
+
+### Scan Container Images
+
+Use the `image` argument to run Prowler with the Image provider. Specify the images to scan using the `-I` flag or an image list file.
+
+#### Scan a Single Image
+
+To scan a single container image:
+
+```bash
+prowler image -I alpine:3.18
+```
+
+#### Scan Multiple Images
+
+To scan multiple images, repeat the `-I` flag:
+
+```bash
+prowler image -I nginx:latest -I redis:7 -I python:3.12-slim
+```
+
+#### Scan From an Image List File
+
+For large-scale scanning, provide a file containing one image per line:
+
+```bash
+prowler image --image-list images.txt
+```
+
+The file supports comments (lines starting with `#`) and blank lines:
+
+```text
+# Production images
+nginx:1.25
+redis:7-alpine
+
+# Development images
+python:3.12-slim
+node:20-bookworm
+```
+
+
+Image list files are limited to a maximum of 10,000 lines. Individual image names exceeding 500 characters are automatically skipped with a warning.
+
+
+
+Image names must follow the Open Container Initiative (OCI) reference format. Valid names start with an alphanumeric character and contain only letters, digits, periods, hyphens, underscores, slashes, colons, and `@` symbols. Names containing shell metacharacters (`;`, `|`, `&`, `$`, `` ` ``) are rejected to prevent command injection.
+
+
+Valid examples:
+* **Standard tag:** `alpine:3.18`
+* **Custom registry:** `myregistry.io/myapp:v1.0`
+* **SHA digest:** `ghcr.io/org/image@sha256:abc123...`
+
+#### Specify Scanners
+
+To select which scanners Trivy runs, use the `--scanners` option. By default, Prowler enables `vuln` and `secret` scanners:
+
+```bash
+# Vulnerability scanning only
+prowler image -I alpine:3.18 --scanners vuln
+
+# All available scanners
+prowler image -I alpine:3.18 --scanners vuln secret misconfig license
+```
+
+
+#### Image Config Scanners
+
+To scan Dockerfile-level metadata for misconfigurations or embedded secrets, use the `--image-config-scanners` option:
+
+```bash
+# Scan Dockerfile for misconfigurations
+prowler image -I alpine:3.18 --image-config-scanners misconfig
+
+# Scan Dockerfile for both misconfigurations and secrets
+prowler image -I alpine:3.18 --image-config-scanners misconfig secret
+```
+
+Available image config scanners:
+
+* **misconfig**: Detects Dockerfile misconfigurations (e.g., running as root, missing health checks)
+* **secret**: Identifies secrets embedded in Dockerfile instructions
+
+
+Image config scanners are disabled by default. This option is independent from `--scanners` and specifically targets the image configuration (Dockerfile) rather than the image filesystem.
+
+
+#### Filter by Severity
+
+To filter findings by severity level, use the `--trivy-severity` option:
+
+```bash
+# Only critical and high severity findings
+prowler image -I alpine:3.18 --trivy-severity CRITICAL HIGH
+```
+
+Available severity levels: `CRITICAL`, `HIGH`, `MEDIUM`, `LOW`, `UNKNOWN`.
+
+#### Ignore Unfixed Vulnerabilities
+
+To exclude vulnerabilities without available fixes:
+
+```bash
+prowler image -I alpine:3.18 --ignore-unfixed
+```
+
+#### Configure Scan Timeout
+
+To adjust the scan timeout for large images or slow network conditions, use the `--timeout` option:
+
+```bash
+prowler image -I large-image:latest --timeout 10m
+```
+
+The timeout accepts values in seconds (`s`), minutes (`m`), or hours (`h`). Default: `5m`.
+
+### Authentication for Private Registries
+
+The Image provider relies on Trivy for registry authentication. To scan images from private registries, configure Docker credentials before running the scan:
+
+```bash
+# Log in to a private registry
+docker login myregistry.io
+
+# Then scan the image
+prowler image -I myregistry.io/myapp:v1.0
+```
+
+Trivy automatically uses credentials from Docker's credential store (`~/.docker/config.json`).
+
+### Troubleshooting Common Scan Errors
+
+The Image provider categorizes common Trivy errors with actionable guidance:
+
+* **Authentication failure (401/403):** Registry credentials are missing or invalid. Run `docker login` for the target registry and retry the scan.
+* **Image not found (404):** The specified image name, tag, or registry is incorrect. Verify the image reference exists and is accessible.
+* **Rate limited (429):** The container registry is throttling requests. Wait before retrying, or authenticate to increase rate limits.
+* **Network issue:** Trivy cannot reach the registry due to connectivity problems. Check network access, DNS resolution, and firewall rules.
diff --git a/docs/user-guide/tutorials/prowler-app-sso.mdx b/docs/user-guide/tutorials/prowler-app-sso.mdx
index fa062100d1..f823fae3df 100644
--- a/docs/user-guide/tutorials/prowler-app-sso.mdx
+++ b/docs/user-guide/tutorials/prowler-app-sso.mdx
@@ -53,7 +53,7 @@ On the profile page, find the "SAML SSO Integration" card and click "Enable" to

-Next section will explain how to fill the IdP configuration based on your Identity Provider.
+The next section explains how to configure the IdP settings based on the selected Identity Provider.
#### Step 3: Configure the Identity Provider (IdP)
Choose a Method:
@@ -79,6 +79,31 @@ Choose a Method:
+ **Configure Attribute Mapping in the IdP**
+
+ For Prowler App to correctly identify and provision users, configure the IdP to send the following attributes in the SAML assertion:
+
+ | Attribute Name | Description | Required |
+ |----------------|---------------------------------------------------------------------------------------------------------|----------|
+ | `firstName` | The user's first name. | Yes |
+ | `lastName` | The user's last name. | Yes |
+ | `userType` | Determines which Prowler role the user receives (e.g., `admin`, `auditor`). If a role with that name already exists, the user receives it automatically; if it does not exist, Prowler App creates a new role with that name without permissions. If `userType` is not defined, the user is assigned the `no_permissions` role. Role permissions can be edited in the [RBAC Management tab](/user-guide/tutorials/prowler-app-rbac). | No |
+ | `companyName` | The user's company name. This is automatically populated if the IdP sends an `organization` attribute. | No |
+
+
+ **IdP Attribute Mapping**
+
+ Note that the attribute name is just an example and may be different depending on the IdP. For instance, if the IdP provides a `division` attribute, it can be mapped to `userType`.
+ 
+
+
+
+ **Dynamic Updates**
+
+ Prowler App updates these attributes each time a user logs in. Any changes made in the Identity Provider (IdP) will be reflected when the user logs in again.
+
+
+
Instead of creating a custom SAML integration, Okta administrators can configure Prowler Cloud directly from Okta's application catalog.
@@ -105,39 +130,48 @@ Choose a Method:
6. **Assign Users**: Navigate to the "Assignments" tab and assign the appropriate users or groups to the Prowler application by clicking "Assign" and selecting "Assign to People" or "Assign to Groups".
+ 
+
+ 7. **Configure User Attributes in Okta**: Okta acts as the central source for user profile information. Prowler App maps the following Okta user profile attributes during each SAML login:
+
+ * **First name** (`firstName`): Maps to the user's first name in Prowler App.
+ * **Last name** (`lastName`): Maps to the user's last name in Prowler App.
+
+ 
+
+ * **Organization** (`organization`): Maps to the company name displayed in Prowler App. This attribute is optional.
+ * **User type** (`userType`): Determines the Prowler role assigned to the user. This attribute is **case-sensitive** and must match the exact name of an existing role in Prowler App.
+
+ 
+
+ To modify these values, edit the user's profile directly in the Okta admin console under the "Profile" tab. Changes are reflected in Prowler App the next time the user logs in via SAML.
+
+
+ **User Type and Role Assignment**
+
+ The `userType` attribute controls which Prowler role is assigned to the user:
+
+ * If a role with the specified name already exists in Prowler App, the user automatically receives that role.
+ * If the role does not exist, Prowler App creates a new role with that exact name but without any permissions, preventing the user from performing any actions.
+ * If `userType` is not defined in the user's Okta profile, the user is assigned the `no_permissions` role.
+
+ In all cases where the resulting role has no permissions, a Prowler administrator (a user whose role includes the "Manage Account" permission) must configure the appropriate permissions through the [RBAC Management tab](/user-guide/tutorials/prowler-app-rbac).
+
+ This behavior is intentional: by defaulting to no permissions, Prowler App ensures that a misconfiguration in Okta cannot inadvertently grant elevated access.
+
+ **Example:** To assign the `IT` role to a user, set the `userType` value to `IT` in Okta. If a role named `IT` already exists in Prowler App, the user receives it automatically upon login. If it does not exist, Prowler App creates a new role called `IT` without permissions, and a Prowler administrator must configure the desired permissions for it.
+
+
+
With this step, the Okta app catalog configuration is complete. Users can now access Prowler Cloud using either [IdP-initiated](#idp-initiated-sso) or [SP-initiated SSO](#sp-initiated-sso) flows.
- 7. **Download Metadata XML**: Inside the "Sign On" section, go to the "Metadata URL" and download the metadata XML file.
+ 8. **Download Metadata XML**: Inside the "Sign On" section, go to the "Metadata URL" and download the metadata XML file.
- Jump to [Step 5: Upload IdP Metadata to Prowler](#step-5:-upload-idp-metadata-to-prowler).
+ Jump to [Step 4: Upload IdP Metadata to Prowler](#step-4:-upload-idp-metadata-to-prowler).
-#### Step 4: Configure Attribute Mapping in the IdP
-
-For Prowler App to correctly identify and provision users, configure the IdP to send the following attributes in the SAML assertion:
-
-| Attribute Name | Description | Required |
-|----------------|---------------------------------------------------------------------------------------------------------|----------|
-| `firstName` | The user's first name. | Yes |
-| `lastName` | The user's last name. | Yes |
-| `userType` | The Prowler role to be assigned to the user (e.g., `admin`, `auditor`). If a role with that name already exists, it will be used; otherwise, a new role called `no_permissions` will be created with minimal permissions. Role permissions can be edited in the [RBAC Management tab](/user-guide/tutorials/prowler-app-rbac). | No |
-| `companyName` | The user's company name. This is automatically populated if the IdP sends an `organization` attribute. | No |
-
-
-**IdP Attribute Mapping**
-
-Note that the attribute name is just an example and may be different depending on the IdP. For instance, if the IdP provides a `division` attribute, it can be mapped to `userType`.
-
-
-
-
-**Dynamic Updates**
-
-Prowler App updates these attributes each time a user logs in. Any changes made in the Identity Provider (IdP) will be reflected when the user logs in again.
-
-
-#### Step 5: Upload IdP Metadata to Prowler
+#### Step 4: Upload IdP Metadata to Prowler
Once the IdP is configured, it provides a **metadata XML file**. This file contains the IdP's configuration information, such as its public key and login URL.
@@ -151,7 +185,7 @@ To complete the Prowler App configuration:

-#### Step 6: Save and Verify Configuration
+#### Step 5: Save and Verify Configuration
Click the "Save" button to complete the setup. The "SAML Integration" card will now display an "Active" status, indicating the configuration is complete and enabled.
diff --git a/poetry.lock b/poetry.lock
index f4d82258e7..2b403394ab 100644
--- a/poetry.lock
+++ b/poetry.lock
@@ -4869,21 +4869,21 @@ files = [
[[package]]
name = "pydantic"
-version = "2.11.7"
+version = "2.12.5"
description = "Data validation using Python type hints"
optional = false
python-versions = ">=3.9"
groups = ["main", "dev"]
files = [
- {file = "pydantic-2.11.7-py3-none-any.whl", hash = "sha256:dde5df002701f6de26248661f6835bbe296a47bf73990135c7d07ce741b9623b"},
- {file = "pydantic-2.11.7.tar.gz", hash = "sha256:d989c3c6cb79469287b1569f7447a17848c998458d49ebe294e975b9baf0f0db"},
+ {file = "pydantic-2.12.5-py3-none-any.whl", hash = "sha256:e561593fccf61e8a20fc46dfc2dfe075b8be7d0188df33f221ad1f0139180f9d"},
+ {file = "pydantic-2.12.5.tar.gz", hash = "sha256:4d351024c75c0f085a9febbb665ce8c0c6ec5d30e903bdb6394b7ede26aebb49"},
]
[package.dependencies]
annotated-types = ">=0.6.0"
-pydantic-core = "2.33.2"
-typing-extensions = ">=4.12.2"
-typing-inspection = ">=0.4.0"
+pydantic-core = "2.41.5"
+typing-extensions = ">=4.14.1"
+typing-inspection = ">=0.4.2"
[package.extras]
email = ["email-validator (>=2.0.0)"]
@@ -4891,115 +4891,137 @@ timezone = ["tzdata ; python_version >= \"3.9\" and platform_system == \"Windows
[[package]]
name = "pydantic-core"
-version = "2.33.2"
+version = "2.41.5"
description = "Core functionality for Pydantic validation and serialization"
optional = false
python-versions = ">=3.9"
groups = ["main", "dev"]
files = [
- {file = "pydantic_core-2.33.2-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:2b3d326aaef0c0399d9afffeb6367d5e26ddc24d351dbc9c636840ac355dc5d8"},
- {file = "pydantic_core-2.33.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0e5b2671f05ba48b94cb90ce55d8bdcaaedb8ba00cc5359f6810fc918713983d"},
- {file = "pydantic_core-2.33.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0069c9acc3f3981b9ff4cdfaf088e98d83440a4c7ea1bc07460af3d4dc22e72d"},
- {file = "pydantic_core-2.33.2-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d53b22f2032c42eaaf025f7c40c2e3b94568ae077a606f006d206a463bc69572"},
- {file = "pydantic_core-2.33.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0405262705a123b7ce9f0b92f123334d67b70fd1f20a9372b907ce1080c7ba02"},
- {file = "pydantic_core-2.33.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4b25d91e288e2c4e0662b8038a28c6a07eaac3e196cfc4ff69de4ea3db992a1b"},
- {file = "pydantic_core-2.33.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6bdfe4b3789761f3bcb4b1ddf33355a71079858958e3a552f16d5af19768fef2"},
- {file = "pydantic_core-2.33.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:efec8db3266b76ef9607c2c4c419bdb06bf335ae433b80816089ea7585816f6a"},
- {file = "pydantic_core-2.33.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:031c57d67ca86902726e0fae2214ce6770bbe2f710dc33063187a68744a5ecac"},
- {file = "pydantic_core-2.33.2-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:f8de619080e944347f5f20de29a975c2d815d9ddd8be9b9b7268e2e3ef68605a"},
- {file = "pydantic_core-2.33.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:73662edf539e72a9440129f231ed3757faab89630d291b784ca99237fb94db2b"},
- {file = "pydantic_core-2.33.2-cp310-cp310-win32.whl", hash = "sha256:0a39979dcbb70998b0e505fb1556a1d550a0781463ce84ebf915ba293ccb7e22"},
- {file = "pydantic_core-2.33.2-cp310-cp310-win_amd64.whl", hash = "sha256:b0379a2b24882fef529ec3b4987cb5d003b9cda32256024e6fe1586ac45fc640"},
- {file = "pydantic_core-2.33.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:4c5b0a576fb381edd6d27f0a85915c6daf2f8138dc5c267a57c08a62900758c7"},
- {file = "pydantic_core-2.33.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e799c050df38a639db758c617ec771fd8fb7a5f8eaaa4b27b101f266b216a246"},
- {file = "pydantic_core-2.33.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dc46a01bf8d62f227d5ecee74178ffc448ff4e5197c756331f71efcc66dc980f"},
- {file = "pydantic_core-2.33.2-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a144d4f717285c6d9234a66778059f33a89096dfb9b39117663fd8413d582dcc"},
- {file = "pydantic_core-2.33.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:73cf6373c21bc80b2e0dc88444f41ae60b2f070ed02095754eb5a01df12256de"},
- {file = "pydantic_core-2.33.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3dc625f4aa79713512d1976fe9f0bc99f706a9dee21dfd1810b4bbbf228d0e8a"},
- {file = "pydantic_core-2.33.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:881b21b5549499972441da4758d662aeea93f1923f953e9cbaff14b8b9565aef"},
- {file = "pydantic_core-2.33.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:bdc25f3681f7b78572699569514036afe3c243bc3059d3942624e936ec93450e"},
- {file = "pydantic_core-2.33.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:fe5b32187cbc0c862ee201ad66c30cf218e5ed468ec8dc1cf49dec66e160cc4d"},
- {file = "pydantic_core-2.33.2-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:bc7aee6f634a6f4a95676fcb5d6559a2c2a390330098dba5e5a5f28a2e4ada30"},
- {file = "pydantic_core-2.33.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:235f45e5dbcccf6bd99f9f472858849f73d11120d76ea8707115415f8e5ebebf"},
- {file = "pydantic_core-2.33.2-cp311-cp311-win32.whl", hash = "sha256:6368900c2d3ef09b69cb0b913f9f8263b03786e5b2a387706c5afb66800efd51"},
- {file = "pydantic_core-2.33.2-cp311-cp311-win_amd64.whl", hash = "sha256:1e063337ef9e9820c77acc768546325ebe04ee38b08703244c1309cccc4f1bab"},
- {file = "pydantic_core-2.33.2-cp311-cp311-win_arm64.whl", hash = "sha256:6b99022f1d19bc32a4c2a0d544fc9a76e3be90f0b3f4af413f87d38749300e65"},
- {file = "pydantic_core-2.33.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:a7ec89dc587667f22b6a0b6579c249fca9026ce7c333fc142ba42411fa243cdc"},
- {file = "pydantic_core-2.33.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3c6db6e52c6d70aa0d00d45cdb9b40f0433b96380071ea80b09277dba021ddf7"},
- {file = "pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e61206137cbc65e6d5256e1166f88331d3b6238e082d9f74613b9b765fb9025"},
- {file = "pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:eb8c529b2819c37140eb51b914153063d27ed88e3bdc31b71198a198e921e011"},
- {file = "pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c52b02ad8b4e2cf14ca7b3d918f3eb0ee91e63b3167c32591e57c4317e134f8f"},
- {file = "pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:96081f1605125ba0855dfda83f6f3df5ec90c61195421ba72223de35ccfb2f88"},
- {file = "pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f57a69461af2a5fa6e6bbd7a5f60d3b7e6cebb687f55106933188e79ad155c1"},
- {file = "pydantic_core-2.33.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:572c7e6c8bb4774d2ac88929e3d1f12bc45714ae5ee6d9a788a9fb35e60bb04b"},
- {file = "pydantic_core-2.33.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:db4b41f9bd95fbe5acd76d89920336ba96f03e149097365afe1cb092fceb89a1"},
- {file = "pydantic_core-2.33.2-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:fa854f5cf7e33842a892e5c73f45327760bc7bc516339fda888c75ae60edaeb6"},
- {file = "pydantic_core-2.33.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:5f483cfb75ff703095c59e365360cb73e00185e01aaea067cd19acffd2ab20ea"},
- {file = "pydantic_core-2.33.2-cp312-cp312-win32.whl", hash = "sha256:9cb1da0f5a471435a7bc7e439b8a728e8b61e59784b2af70d7c169f8dd8ae290"},
- {file = "pydantic_core-2.33.2-cp312-cp312-win_amd64.whl", hash = "sha256:f941635f2a3d96b2973e867144fde513665c87f13fe0e193c158ac51bfaaa7b2"},
- {file = "pydantic_core-2.33.2-cp312-cp312-win_arm64.whl", hash = "sha256:cca3868ddfaccfbc4bfb1d608e2ccaaebe0ae628e1416aeb9c4d88c001bb45ab"},
- {file = "pydantic_core-2.33.2-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:1082dd3e2d7109ad8b7da48e1d4710c8d06c253cbc4a27c1cff4fbcaa97a9e3f"},
- {file = "pydantic_core-2.33.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f517ca031dfc037a9c07e748cefd8d96235088b83b4f4ba8939105d20fa1dcd6"},
- {file = "pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0a9f2c9dd19656823cb8250b0724ee9c60a82f3cdf68a080979d13092a3b0fef"},
- {file = "pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2b0a451c263b01acebe51895bfb0e1cc842a5c666efe06cdf13846c7418caa9a"},
- {file = "pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ea40a64d23faa25e62a70ad163571c0b342b8bf66d5fa612ac0dec4f069d916"},
- {file = "pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0fb2d542b4d66f9470e8065c5469ec676978d625a8b7a363f07d9a501a9cb36a"},
- {file = "pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9fdac5d6ffa1b5a83bca06ffe7583f5576555e6c8b3a91fbd25ea7780f825f7d"},
- {file = "pydantic_core-2.33.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:04a1a413977ab517154eebb2d326da71638271477d6ad87a769102f7c2488c56"},
- {file = "pydantic_core-2.33.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:c8e7af2f4e0194c22b5b37205bfb293d166a7344a5b0d0eaccebc376546d77d5"},
- {file = "pydantic_core-2.33.2-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:5c92edd15cd58b3c2d34873597a1e20f13094f59cf88068adb18947df5455b4e"},
- {file = "pydantic_core-2.33.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:65132b7b4a1c0beded5e057324b7e16e10910c106d43675d9bd87d4f38dde162"},
- {file = "pydantic_core-2.33.2-cp313-cp313-win32.whl", hash = "sha256:52fb90784e0a242bb96ec53f42196a17278855b0f31ac7c3cc6f5c1ec4811849"},
- {file = "pydantic_core-2.33.2-cp313-cp313-win_amd64.whl", hash = "sha256:c083a3bdd5a93dfe480f1125926afcdbf2917ae714bdb80b36d34318b2bec5d9"},
- {file = "pydantic_core-2.33.2-cp313-cp313-win_arm64.whl", hash = "sha256:e80b087132752f6b3d714f041ccf74403799d3b23a72722ea2e6ba2e892555b9"},
- {file = "pydantic_core-2.33.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:61c18fba8e5e9db3ab908620af374db0ac1baa69f0f32df4f61ae23f15e586ac"},
- {file = "pydantic_core-2.33.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95237e53bb015f67b63c91af7518a62a8660376a6a0db19b89acc77a4d6199f5"},
- {file = "pydantic_core-2.33.2-cp313-cp313t-win_amd64.whl", hash = "sha256:c2fc0a768ef76c15ab9238afa6da7f69895bb5d1ee83aeea2e3509af4472d0b9"},
- {file = "pydantic_core-2.33.2-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:a2b911a5b90e0374d03813674bf0a5fbbb7741570dcd4b4e85a2e48d17def29d"},
- {file = "pydantic_core-2.33.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:6fa6dfc3e4d1f734a34710f391ae822e0a8eb8559a85c6979e14e65ee6ba2954"},
- {file = "pydantic_core-2.33.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c54c939ee22dc8e2d545da79fc5381f1c020d6d3141d3bd747eab59164dc89fb"},
- {file = "pydantic_core-2.33.2-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:53a57d2ed685940a504248187d5685e49eb5eef0f696853647bf37c418c538f7"},
- {file = "pydantic_core-2.33.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:09fb9dd6571aacd023fe6aaca316bd01cf60ab27240d7eb39ebd66a3a15293b4"},
- {file = "pydantic_core-2.33.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0e6116757f7959a712db11f3e9c0a99ade00a5bbedae83cb801985aa154f071b"},
- {file = "pydantic_core-2.33.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8d55ab81c57b8ff8548c3e4947f119551253f4e3787a7bbc0b6b3ca47498a9d3"},
- {file = "pydantic_core-2.33.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c20c462aa4434b33a2661701b861604913f912254e441ab8d78d30485736115a"},
- {file = "pydantic_core-2.33.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:44857c3227d3fb5e753d5fe4a3420d6376fa594b07b621e220cd93703fe21782"},
- {file = "pydantic_core-2.33.2-cp39-cp39-musllinux_1_1_armv7l.whl", hash = "sha256:eb9b459ca4df0e5c87deb59d37377461a538852765293f9e6ee834f0435a93b9"},
- {file = "pydantic_core-2.33.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:9fcd347d2cc5c23b06de6d3b7b8275be558a0c90549495c699e379a80bf8379e"},
- {file = "pydantic_core-2.33.2-cp39-cp39-win32.whl", hash = "sha256:83aa99b1285bc8f038941ddf598501a86f1536789740991d7d8756e34f1e74d9"},
- {file = "pydantic_core-2.33.2-cp39-cp39-win_amd64.whl", hash = "sha256:f481959862f57f29601ccced557cc2e817bce7533ab8e01a797a48b49c9692b3"},
- {file = "pydantic_core-2.33.2-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:5c4aa4e82353f65e548c476b37e64189783aa5384903bfea4f41580f255fddfa"},
- {file = "pydantic_core-2.33.2-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:d946c8bf0d5c24bf4fe333af284c59a19358aa3ec18cb3dc4370080da1e8ad29"},
- {file = "pydantic_core-2.33.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:87b31b6846e361ef83fedb187bb5b4372d0da3f7e28d85415efa92d6125d6e6d"},
- {file = "pydantic_core-2.33.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aa9d91b338f2df0508606f7009fde642391425189bba6d8c653afd80fd6bb64e"},
- {file = "pydantic_core-2.33.2-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2058a32994f1fde4ca0480ab9d1e75a0e8c87c22b53a3ae66554f9af78f2fe8c"},
- {file = "pydantic_core-2.33.2-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:0e03262ab796d986f978f79c943fc5f620381be7287148b8010b4097f79a39ec"},
- {file = "pydantic_core-2.33.2-pp310-pypy310_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:1a8695a8d00c73e50bff9dfda4d540b7dee29ff9b8053e38380426a85ef10052"},
- {file = "pydantic_core-2.33.2-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:fa754d1850735a0b0e03bcffd9d4b4343eb417e47196e4485d9cca326073a42c"},
- {file = "pydantic_core-2.33.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:a11c8d26a50bfab49002947d3d237abe4d9e4b5bdc8846a63537b6488e197808"},
- {file = "pydantic_core-2.33.2-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:dd14041875d09cc0f9308e37a6f8b65f5585cf2598a53aa0123df8b129d481f8"},
- {file = "pydantic_core-2.33.2-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:d87c561733f66531dced0da6e864f44ebf89a8fba55f31407b00c2f7f9449593"},
- {file = "pydantic_core-2.33.2-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f82865531efd18d6e07a04a17331af02cb7a651583c418df8266f17a63c6612"},
- {file = "pydantic_core-2.33.2-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2bfb5112df54209d820d7bf9317c7a6c9025ea52e49f46b6a2060104bba37de7"},
- {file = "pydantic_core-2.33.2-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:64632ff9d614e5eecfb495796ad51b0ed98c453e447a76bcbeeb69615079fc7e"},
- {file = "pydantic_core-2.33.2-pp311-pypy311_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:f889f7a40498cc077332c7ab6b4608d296d852182211787d4f3ee377aaae66e8"},
- {file = "pydantic_core-2.33.2-pp311-pypy311_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:de4b83bb311557e439b9e186f733f6c645b9417c84e2eb8203f3f820a4b988bf"},
- {file = "pydantic_core-2.33.2-pp311-pypy311_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:82f68293f055f51b51ea42fafc74b6aad03e70e191799430b90c13d643059ebb"},
- {file = "pydantic_core-2.33.2-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:329467cecfb529c925cf2bbd4d60d2c509bc2fb52a20c1045bf09bb70971a9c1"},
- {file = "pydantic_core-2.33.2-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:87acbfcf8e90ca885206e98359d7dca4bcbb35abdc0ff66672a293e1d7a19101"},
- {file = "pydantic_core-2.33.2-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:7f92c15cd1e97d4b12acd1cc9004fa092578acfa57b67ad5e43a197175d01a64"},
- {file = "pydantic_core-2.33.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d3f26877a748dc4251cfcfda9dfb5f13fcb034f5308388066bcfe9031b63ae7d"},
- {file = "pydantic_core-2.33.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dac89aea9af8cd672fa7b510e7b8c33b0bba9a43186680550ccf23020f32d535"},
- {file = "pydantic_core-2.33.2-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:970919794d126ba8645f3837ab6046fb4e72bbc057b3709144066204c19a455d"},
- {file = "pydantic_core-2.33.2-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:3eb3fe62804e8f859c49ed20a8451342de53ed764150cb14ca71357c765dc2a6"},
- {file = "pydantic_core-2.33.2-pp39-pypy39_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:3abcd9392a36025e3bd55f9bd38d908bd17962cc49bc6da8e7e96285336e2bca"},
- {file = "pydantic_core-2.33.2-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:3a1c81334778f9e3af2f8aeb7a960736e5cab1dfebfb26aabca09afd2906c039"},
- {file = "pydantic_core-2.33.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:2807668ba86cb38c6817ad9bc66215ab8584d1d304030ce4f0887336f28a5e27"},
- {file = "pydantic_core-2.33.2.tar.gz", hash = "sha256:7cb8bc3605c29176e1b105350d2e6474142d7c1bd1d9327c4a9bdb46bf827acc"},
+ {file = "pydantic_core-2.41.5-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:77b63866ca88d804225eaa4af3e664c5faf3568cea95360d21f4725ab6e07146"},
+ {file = "pydantic_core-2.41.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:dfa8a0c812ac681395907e71e1274819dec685fec28273a28905df579ef137e2"},
+ {file = "pydantic_core-2.41.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5921a4d3ca3aee735d9fd163808f5e8dd6c6972101e4adbda9a4667908849b97"},
+ {file = "pydantic_core-2.41.5-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e25c479382d26a2a41b7ebea1043564a937db462816ea07afa8a44c0866d52f9"},
+ {file = "pydantic_core-2.41.5-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f547144f2966e1e16ae626d8ce72b4cfa0caedc7fa28052001c94fb2fcaa1c52"},
+ {file = "pydantic_core-2.41.5-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6f52298fbd394f9ed112d56f3d11aabd0d5bd27beb3084cc3d8ad069483b8941"},
+ {file = "pydantic_core-2.41.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:100baa204bb412b74fe285fb0f3a385256dad1d1879f0a5cb1499ed2e83d132a"},
+ {file = "pydantic_core-2.41.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:05a2c8852530ad2812cb7914dc61a1125dc4e06252ee98e5638a12da6cc6fb6c"},
+ {file = "pydantic_core-2.41.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:29452c56df2ed968d18d7e21f4ab0ac55e71dc59524872f6fc57dcf4a3249ed2"},
+ {file = "pydantic_core-2.41.5-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:d5160812ea7a8a2ffbe233d8da666880cad0cbaf5d4de74ae15c313213d62556"},
+ {file = "pydantic_core-2.41.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:df3959765b553b9440adfd3c795617c352154e497a4eaf3752555cfb5da8fc49"},
+ {file = "pydantic_core-2.41.5-cp310-cp310-win32.whl", hash = "sha256:1f8d33a7f4d5a7889e60dc39856d76d09333d8a6ed0f5f1190635cbec70ec4ba"},
+ {file = "pydantic_core-2.41.5-cp310-cp310-win_amd64.whl", hash = "sha256:62de39db01b8d593e45871af2af9e497295db8d73b085f6bfd0b18c83c70a8f9"},
+ {file = "pydantic_core-2.41.5-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:a3a52f6156e73e7ccb0f8cced536adccb7042be67cb45f9562e12b319c119da6"},
+ {file = "pydantic_core-2.41.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7f3bf998340c6d4b0c9a2f02d6a400e51f123b59565d74dc60d252ce888c260b"},
+ {file = "pydantic_core-2.41.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:378bec5c66998815d224c9ca994f1e14c0c21cb95d2f52b6021cc0b2a58f2a5a"},
+ {file = "pydantic_core-2.41.5-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e7b576130c69225432866fe2f4a469a85a54ade141d96fd396dffcf607b558f8"},
+ {file = "pydantic_core-2.41.5-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6cb58b9c66f7e4179a2d5e0f849c48eff5c1fca560994d6eb6543abf955a149e"},
+ {file = "pydantic_core-2.41.5-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:88942d3a3dff3afc8288c21e565e476fc278902ae4d6d134f1eeda118cc830b1"},
+ {file = "pydantic_core-2.41.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f31d95a179f8d64d90f6831d71fa93290893a33148d890ba15de25642c5d075b"},
+ {file = "pydantic_core-2.41.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c1df3d34aced70add6f867a8cf413e299177e0c22660cc767218373d0779487b"},
+ {file = "pydantic_core-2.41.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:4009935984bd36bd2c774e13f9a09563ce8de4abaa7226f5108262fa3e637284"},
+ {file = "pydantic_core-2.41.5-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:34a64bc3441dc1213096a20fe27e8e128bd3ff89921706e83c0b1ac971276594"},
+ {file = "pydantic_core-2.41.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:c9e19dd6e28fdcaa5a1de679aec4141f691023916427ef9bae8584f9c2fb3b0e"},
+ {file = "pydantic_core-2.41.5-cp311-cp311-win32.whl", hash = "sha256:2c010c6ded393148374c0f6f0bf89d206bf3217f201faa0635dcd56bd1520f6b"},
+ {file = "pydantic_core-2.41.5-cp311-cp311-win_amd64.whl", hash = "sha256:76ee27c6e9c7f16f47db7a94157112a2f3a00e958bc626e2f4ee8bec5c328fbe"},
+ {file = "pydantic_core-2.41.5-cp311-cp311-win_arm64.whl", hash = "sha256:4bc36bbc0b7584de96561184ad7f012478987882ebf9f9c389b23f432ea3d90f"},
+ {file = "pydantic_core-2.41.5-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:f41a7489d32336dbf2199c8c0a215390a751c5b014c2c1c5366e817202e9cdf7"},
+ {file = "pydantic_core-2.41.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:070259a8818988b9a84a449a2a7337c7f430a22acc0859c6b110aa7212a6d9c0"},
+ {file = "pydantic_core-2.41.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e96cea19e34778f8d59fe40775a7a574d95816eb150850a85a7a4c8f4b94ac69"},
+ {file = "pydantic_core-2.41.5-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ed2e99c456e3fadd05c991f8f437ef902e00eedf34320ba2b0842bd1c3ca3a75"},
+ {file = "pydantic_core-2.41.5-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:65840751b72fbfd82c3c640cff9284545342a4f1eb1586ad0636955b261b0b05"},
+ {file = "pydantic_core-2.41.5-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e536c98a7626a98feb2d3eaf75944ef6f3dbee447e1f841eae16f2f0a72d8ddc"},
+ {file = "pydantic_core-2.41.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eceb81a8d74f9267ef4081e246ffd6d129da5d87e37a77c9bde550cb04870c1c"},
+ {file = "pydantic_core-2.41.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d38548150c39b74aeeb0ce8ee1d8e82696f4a4e16ddc6de7b1d8823f7de4b9b5"},
+ {file = "pydantic_core-2.41.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:c23e27686783f60290e36827f9c626e63154b82b116d7fe9adba1fda36da706c"},
+ {file = "pydantic_core-2.41.5-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:482c982f814460eabe1d3bb0adfdc583387bd4691ef00b90575ca0d2b6fe2294"},
+ {file = "pydantic_core-2.41.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:bfea2a5f0b4d8d43adf9d7b8bf019fb46fdd10a2e5cde477fbcb9d1fa08c68e1"},
+ {file = "pydantic_core-2.41.5-cp312-cp312-win32.whl", hash = "sha256:b74557b16e390ec12dca509bce9264c3bbd128f8a2c376eaa68003d7f327276d"},
+ {file = "pydantic_core-2.41.5-cp312-cp312-win_amd64.whl", hash = "sha256:1962293292865bca8e54702b08a4f26da73adc83dd1fcf26fbc875b35d81c815"},
+ {file = "pydantic_core-2.41.5-cp312-cp312-win_arm64.whl", hash = "sha256:1746d4a3d9a794cacae06a5eaaccb4b8643a131d45fbc9af23e353dc0a5ba5c3"},
+ {file = "pydantic_core-2.41.5-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:941103c9be18ac8daf7b7adca8228f8ed6bb7a1849020f643b3a14d15b1924d9"},
+ {file = "pydantic_core-2.41.5-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:112e305c3314f40c93998e567879e887a3160bb8689ef3d2c04b6cc62c33ac34"},
+ {file = "pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0cbaad15cb0c90aa221d43c00e77bb33c93e8d36e0bf74760cd00e732d10a6a0"},
+ {file = "pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:03ca43e12fab6023fc79d28ca6b39b05f794ad08ec2feccc59a339b02f2b3d33"},
+ {file = "pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dc799088c08fa04e43144b164feb0c13f9a0bc40503f8df3e9fde58a3c0c101e"},
+ {file = "pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:97aeba56665b4c3235a0e52b2c2f5ae9cd071b8a8310ad27bddb3f7fb30e9aa2"},
+ {file = "pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:406bf18d345822d6c21366031003612b9c77b3e29ffdb0f612367352aab7d586"},
+ {file = "pydantic_core-2.41.5-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b93590ae81f7010dbe380cdeab6f515902ebcbefe0b9327cc4804d74e93ae69d"},
+ {file = "pydantic_core-2.41.5-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:01a3d0ab748ee531f4ea6c3e48ad9dac84ddba4b0d82291f87248f2f9de8d740"},
+ {file = "pydantic_core-2.41.5-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:6561e94ba9dacc9c61bce40e2d6bdc3bfaa0259d3ff36ace3b1e6901936d2e3e"},
+ {file = "pydantic_core-2.41.5-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:915c3d10f81bec3a74fbd4faebe8391013ba61e5a1a8d48c4455b923bdda7858"},
+ {file = "pydantic_core-2.41.5-cp313-cp313-win32.whl", hash = "sha256:650ae77860b45cfa6e2cdafc42618ceafab3a2d9a3811fcfbd3bbf8ac3c40d36"},
+ {file = "pydantic_core-2.41.5-cp313-cp313-win_amd64.whl", hash = "sha256:79ec52ec461e99e13791ec6508c722742ad745571f234ea6255bed38c6480f11"},
+ {file = "pydantic_core-2.41.5-cp313-cp313-win_arm64.whl", hash = "sha256:3f84d5c1b4ab906093bdc1ff10484838aca54ef08de4afa9de0f5f14d69639cd"},
+ {file = "pydantic_core-2.41.5-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:3f37a19d7ebcdd20b96485056ba9e8b304e27d9904d233d7b1015db320e51f0a"},
+ {file = "pydantic_core-2.41.5-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:1d1d9764366c73f996edd17abb6d9d7649a7eb690006ab6adbda117717099b14"},
+ {file = "pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:25e1c2af0fce638d5f1988b686f3b3ea8cd7de5f244ca147c777769e798a9cd1"},
+ {file = "pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:506d766a8727beef16b7adaeb8ee6217c64fc813646b424d0804d67c16eddb66"},
+ {file = "pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4819fa52133c9aa3c387b3328f25c1facc356491e6135b459f1de698ff64d869"},
+ {file = "pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2b761d210c9ea91feda40d25b4efe82a1707da2ef62901466a42492c028553a2"},
+ {file = "pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:22f0fb8c1c583a3b6f24df2470833b40207e907b90c928cc8d3594b76f874375"},
+ {file = "pydantic_core-2.41.5-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2782c870e99878c634505236d81e5443092fba820f0373997ff75f90f68cd553"},
+ {file = "pydantic_core-2.41.5-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:0177272f88ab8312479336e1d777f6b124537d47f2123f89cb37e0accea97f90"},
+ {file = "pydantic_core-2.41.5-cp314-cp314-musllinux_1_1_armv7l.whl", hash = "sha256:63510af5e38f8955b8ee5687740d6ebf7c2a0886d15a6d65c32814613681bc07"},
+ {file = "pydantic_core-2.41.5-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:e56ba91f47764cc14f1daacd723e3e82d1a89d783f0f5afe9c364b8bb491ccdb"},
+ {file = "pydantic_core-2.41.5-cp314-cp314-win32.whl", hash = "sha256:aec5cf2fd867b4ff45b9959f8b20ea3993fc93e63c7363fe6851424c8a7e7c23"},
+ {file = "pydantic_core-2.41.5-cp314-cp314-win_amd64.whl", hash = "sha256:8e7c86f27c585ef37c35e56a96363ab8de4e549a95512445b85c96d3e2f7c1bf"},
+ {file = "pydantic_core-2.41.5-cp314-cp314-win_arm64.whl", hash = "sha256:e672ba74fbc2dc8eea59fb6d4aed6845e6905fc2a8afe93175d94a83ba2a01a0"},
+ {file = "pydantic_core-2.41.5-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:8566def80554c3faa0e65ac30ab0932b9e3a5cd7f8323764303d468e5c37595a"},
+ {file = "pydantic_core-2.41.5-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:b80aa5095cd3109962a298ce14110ae16b8c1aece8b72f9dafe81cf597ad80b3"},
+ {file = "pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3006c3dd9ba34b0c094c544c6006cc79e87d8612999f1a5d43b769b89181f23c"},
+ {file = "pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:72f6c8b11857a856bcfa48c86f5368439f74453563f951e473514579d44aa612"},
+ {file = "pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5cb1b2f9742240e4bb26b652a5aeb840aa4b417c7748b6f8387927bc6e45e40d"},
+ {file = "pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bd3d54f38609ff308209bd43acea66061494157703364ae40c951f83ba99a1a9"},
+ {file = "pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2ff4321e56e879ee8d2a879501c8e469414d948f4aba74a2d4593184eb326660"},
+ {file = "pydantic_core-2.41.5-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d0d2568a8c11bf8225044aa94409e21da0cb09dcdafe9ecd10250b2baad531a9"},
+ {file = "pydantic_core-2.41.5-cp314-cp314t-musllinux_1_1_aarch64.whl", hash = "sha256:a39455728aabd58ceabb03c90e12f71fd30fa69615760a075b9fec596456ccc3"},
+ {file = "pydantic_core-2.41.5-cp314-cp314t-musllinux_1_1_armv7l.whl", hash = "sha256:239edca560d05757817c13dc17c50766136d21f7cd0fac50295499ae24f90fdf"},
+ {file = "pydantic_core-2.41.5-cp314-cp314t-musllinux_1_1_x86_64.whl", hash = "sha256:2a5e06546e19f24c6a96a129142a75cee553cc018ffee48a460059b1185f4470"},
+ {file = "pydantic_core-2.41.5-cp314-cp314t-win32.whl", hash = "sha256:b4ececa40ac28afa90871c2cc2b9ffd2ff0bf749380fbdf57d165fd23da353aa"},
+ {file = "pydantic_core-2.41.5-cp314-cp314t-win_amd64.whl", hash = "sha256:80aa89cad80b32a912a65332f64a4450ed00966111b6615ca6816153d3585a8c"},
+ {file = "pydantic_core-2.41.5-cp314-cp314t-win_arm64.whl", hash = "sha256:35b44f37a3199f771c3eaa53051bc8a70cd7b54f333531c59e29fd4db5d15008"},
+ {file = "pydantic_core-2.41.5-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:8bfeaf8735be79f225f3fefab7f941c712aaca36f1128c9d7e2352ee1aa87bdf"},
+ {file = "pydantic_core-2.41.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:346285d28e4c8017da95144c7f3acd42740d637ff41946af5ce6e5e420502dd5"},
+ {file = "pydantic_core-2.41.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a75dafbf87d6276ddc5b2bf6fae5254e3d0876b626eb24969a574fff9149ee5d"},
+ {file = "pydantic_core-2.41.5-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7b93a4d08587e2b7e7882de461e82b6ed76d9026ce91ca7915e740ecc7855f60"},
+ {file = "pydantic_core-2.41.5-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e8465ab91a4bd96d36dde3263f06caa6a8a6019e4113f24dc753d79a8b3a3f82"},
+ {file = "pydantic_core-2.41.5-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:299e0a22e7ae2b85c1a57f104538b2656e8ab1873511fd718a1c1c6f149b77b5"},
+ {file = "pydantic_core-2.41.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:707625ef0983fcfb461acfaf14de2067c5942c6bb0f3b4c99158bed6fedd3cf3"},
+ {file = "pydantic_core-2.41.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f41eb9797986d6ebac5e8edff36d5cef9de40def462311b3eb3eeded1431e425"},
+ {file = "pydantic_core-2.41.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0384e2e1021894b1ff5a786dbf94771e2986ebe2869533874d7e43bc79c6f504"},
+ {file = "pydantic_core-2.41.5-cp39-cp39-musllinux_1_1_armv7l.whl", hash = "sha256:f0cd744688278965817fd0839c4a4116add48d23890d468bc436f78beb28abf5"},
+ {file = "pydantic_core-2.41.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:753e230374206729bf0a807954bcc6c150d3743928a73faffee51ac6557a03c3"},
+ {file = "pydantic_core-2.41.5-cp39-cp39-win32.whl", hash = "sha256:873e0d5b4fb9b89ef7c2d2a963ea7d02879d9da0da8d9d4933dee8ee86a8b460"},
+ {file = "pydantic_core-2.41.5-cp39-cp39-win_amd64.whl", hash = "sha256:e4f4a984405e91527a0d62649ee21138f8e3d0ef103be488c1dc11a80d7f184b"},
+ {file = "pydantic_core-2.41.5-graalpy311-graalpy242_311_native-macosx_10_12_x86_64.whl", hash = "sha256:b96d5f26b05d03cc60f11a7761a5ded1741da411e7fe0909e27a5e6a0cb7b034"},
+ {file = "pydantic_core-2.41.5-graalpy311-graalpy242_311_native-macosx_11_0_arm64.whl", hash = "sha256:634e8609e89ceecea15e2d61bc9ac3718caaaa71963717bf3c8f38bfde64242c"},
+ {file = "pydantic_core-2.41.5-graalpy311-graalpy242_311_native-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:93e8740d7503eb008aa2df04d3b9735f845d43ae845e6dcd2be0b55a2da43cd2"},
+ {file = "pydantic_core-2.41.5-graalpy311-graalpy242_311_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f15489ba13d61f670dcc96772e733aad1a6f9c429cc27574c6cdaed82d0146ad"},
+ {file = "pydantic_core-2.41.5-graalpy312-graalpy250_312_native-macosx_10_12_x86_64.whl", hash = "sha256:7da7087d756b19037bc2c06edc6c170eeef3c3bafcb8f532ff17d64dc427adfd"},
+ {file = "pydantic_core-2.41.5-graalpy312-graalpy250_312_native-macosx_11_0_arm64.whl", hash = "sha256:aabf5777b5c8ca26f7824cb4a120a740c9588ed58df9b2d196ce92fba42ff8dc"},
+ {file = "pydantic_core-2.41.5-graalpy312-graalpy250_312_native-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c007fe8a43d43b3969e8469004e9845944f1a80e6acd47c150856bb87f230c56"},
+ {file = "pydantic_core-2.41.5-graalpy312-graalpy250_312_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:76d0819de158cd855d1cbb8fcafdf6f5cf1eb8e470abe056d5d161106e38062b"},
+ {file = "pydantic_core-2.41.5-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:b5819cd790dbf0c5eb9f82c73c16b39a65dd6dd4d1439dcdea7816ec9adddab8"},
+ {file = "pydantic_core-2.41.5-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:5a4e67afbc95fa5c34cf27d9089bca7fcab4e51e57278d710320a70b956d1b9a"},
+ {file = "pydantic_core-2.41.5-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ece5c59f0ce7d001e017643d8d24da587ea1f74f6993467d85ae8a5ef9d4f42b"},
+ {file = "pydantic_core-2.41.5-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:16f80f7abe3351f8ea6858914ddc8c77e02578544a0ebc15b4c2e1a0e813b0b2"},
+ {file = "pydantic_core-2.41.5-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:33cb885e759a705b426baada1fe68cbb0a2e68e34c5d0d0289a364cf01709093"},
+ {file = "pydantic_core-2.41.5-pp310-pypy310_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:c8d8b4eb992936023be7dee581270af5c6e0697a8559895f527f5b7105ecd36a"},
+ {file = "pydantic_core-2.41.5-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:242a206cd0318f95cd21bdacff3fcc3aab23e79bba5cac3db5a841c9ef9c6963"},
+ {file = "pydantic_core-2.41.5-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:d3a978c4f57a597908b7e697229d996d77a6d3c94901e9edee593adada95ce1a"},
+ {file = "pydantic_core-2.41.5-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:b2379fa7ed44ddecb5bfe4e48577d752db9fc10be00a6b7446e9663ba143de26"},
+ {file = "pydantic_core-2.41.5-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:266fb4cbf5e3cbd0b53669a6d1b039c45e3ce651fd5442eff4d07c2cc8d66808"},
+ {file = "pydantic_core-2.41.5-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:58133647260ea01e4d0500089a8c4f07bd7aa6ce109682b1426394988d8aaacc"},
+ {file = "pydantic_core-2.41.5-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:287dad91cfb551c363dc62899a80e9e14da1f0e2b6ebde82c806612ca2a13ef1"},
+ {file = "pydantic_core-2.41.5-pp311-pypy311_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:03b77d184b9eb40240ae9fd676ca364ce1085f203e1b1256f8ab9984dca80a84"},
+ {file = "pydantic_core-2.41.5-pp311-pypy311_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:a668ce24de96165bb239160b3d854943128f4334822900534f2fe947930e5770"},
+ {file = "pydantic_core-2.41.5-pp311-pypy311_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f14f8f046c14563f8eb3f45f499cc658ab8d10072961e07225e507adb700e93f"},
+ {file = "pydantic_core-2.41.5-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:56121965f7a4dc965bff783d70b907ddf3d57f6eba29b6d2e5dabfaf07799c51"},
+ {file = "pydantic_core-2.41.5.tar.gz", hash = "sha256:08daa51ea16ad373ffd5e7606252cc32f07bc72b28284b6bc9c6df804816476e"},
]
[package.dependencies]
-typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0"
+typing-extensions = ">=4.14.1"
[[package]]
name = "pyflakes"
@@ -6303,14 +6325,14 @@ files = [
[[package]]
name = "typing-inspection"
-version = "0.4.1"
+version = "0.4.2"
description = "Runtime typing introspection tools"
optional = false
python-versions = ">=3.9"
groups = ["main", "dev"]
files = [
- {file = "typing_inspection-0.4.1-py3-none-any.whl", hash = "sha256:389055682238f53b04f7badcb49b989835495a96700ced5dab2d8feae4b26f51"},
- {file = "typing_inspection-0.4.1.tar.gz", hash = "sha256:6ae134cc0203c33377d43188d4064e9b357dba58cff3185f22924610e70a9d28"},
+ {file = "typing_inspection-0.4.2-py3-none-any.whl", hash = "sha256:4ed1cacbdc298c220f1bd249ed5287caa16f34d44ef4e9c3d0cbad5b521545e7"},
+ {file = "typing_inspection-0.4.2.tar.gz", hash = "sha256:ba561c48a67c5958007083d386c3295464928b01faa735ab8547c5692e87f464"},
]
[package.dependencies]
diff --git a/prowler/CHANGELOG.md b/prowler/CHANGELOG.md
index 328cf92304..4bfea57e81 100644
--- a/prowler/CHANGELOG.md
+++ b/prowler/CHANGELOG.md
@@ -6,7 +6,69 @@ All notable changes to the **Prowler SDK** are documented in this file.
### 🚀 Added
+- `organization_verified_badge` check for GitHub provider [(#10033)](https://github.com/prowler-cloud/prowler/pull/10033)
+- OpenStack provider `clouds_yaml_content` parameter for API integration [(#10003)](https://github.com/prowler-cloud/prowler/pull/10003)
+- `defender_safe_attachments_policy_enabled` check for M365 provider [(#9833)](https://github.com/prowler-cloud/prowler/pull/9833)
+- `defender_safelinks_policy_enabled` check for M365 provider [(#9832)](https://github.com/prowler-cloud/prowler/pull/9832)
- AI Skills: Added a skill for creating new Attack Paths queries in openCypher, compatible with Neo4j and Neptune [(#9975)](https://github.com/prowler-cloud/prowler/pull/9975)
+- CSA CCM 4.0 for the AWS provider [(#10018)](https://github.com/prowler-cloud/prowler/pull/10018)
+- CSA CCM 4.0 for the GCP provider [(#10042)](https://github.com/prowler-cloud/prowler/pull/10042)
+- CSA CCM 4.0 for the Azure provider [(#10039)](https://github.com/prowler-cloud/prowler/pull/10039)
+- CSA CCM 4.0 for the Oracle Cloud provider [(#10057)](https://github.com/prowler-cloud/prowler/pull/10057)
+- OCI regions updater script and CI workflow [(#10020)](https://github.com/prowler-cloud/prowler/pull/10020)
+- `image` provider for container image scanning with Trivy integration [(#9984)](https://github.com/prowler-cloud/prowler/pull/9984)
+- OpenStack compute 7 new checks [(#9944)](https://github.com/prowler-cloud/prowler/pull/9944)
+- CSA CCM 4.0 for the Alibaba Cloud provider [(#10061)](https://github.com/prowler-cloud/prowler/pull/10061)
+- ECS Exec (ECS-006) privilege escalation detection via `ecs:ExecuteCommand` + `ecs:DescribeTasks` [(#10066)](https://github.com/prowler-cloud/prowler/pull/10066)
+- Add file descriptor limits (`ulimits`) to Docker Compose worker services to prevent `Too many open files` errors [(#10107)](https://github.com/prowler-cloud/prowler/pull/10107)
+
+### 🔄 Changed
+
+- Update Azure Monitor service metadata to new format [(#9622)](https://github.com/prowler-cloud/prowler/pull/9622)
+- GitHub provider enhanced documentation and `repository_branch_delete_on_merge_enabled` logic [(#9830)](https://github.com/prowler-cloud/prowler/pull/9830)
+- Parallelize Cloudflare zone API calls with threading to improve scan performance [(#9982)](https://github.com/prowler-cloud/prowler/pull/9982)
+- Update GCP API Keys service metadata to new format [(#9637)](https://github.com/prowler-cloud/prowler/pull/9637)
+- Update GCP BigQuery service metadata to new format [(#9638)](https://github.com/prowler-cloud/prowler/pull/9638)
+- Update GCP Cloud SQL service metadata to new format [(#9639)](https://github.com/prowler-cloud/prowler/pull/9639)
+- Update GCP Cloud Storage service metadata to new format [(#9640)](https://github.com/prowler-cloud/prowler/pull/9640)
+- Update GCP Compute Engine service metadata to new format [(#9641)](https://github.com/prowler-cloud/prowler/pull/9641)
+- Update GCP Dataproc service metadata to new format [(#9642)](https://github.com/prowler-cloud/prowler/pull/9642)
+- Update GCP DNS service metadata to new format [(#9643)](https://github.com/prowler-cloud/prowler/pull/9643)
+- Update GCP GCR service metadata to new format [(#9644)](https://github.com/prowler-cloud/prowler/pull/9644)
+- Update GCP GKE service metadata to new format [(#9645)](https://github.com/prowler-cloud/prowler/pull/9645)
+- Update GCP IAM service metadata to new format [(#9646)](https://github.com/prowler-cloud/prowler/pull/9646)
+- Update GCP KMS service metadata to new format [(#9647)](https://github.com/prowler-cloud/prowler/pull/9647)
+- Update GCP Logging service metadata to new format [(#9648)](https://github.com/prowler-cloud/prowler/pull/9648)
+- Update Azure Key Vault service metadata to new format [(#9621)](https://github.com/prowler-cloud/prowler/pull/9621)
+- Update Azure Entra ID service metadata to new format [(#9619)](https://github.com/prowler-cloud/prowler/pull/9619)
+- Update Azure Virtual Machines service metadata to new format [(#9629)](https://github.com/prowler-cloud/prowler/pull/9629)
+
+### 🔐 Security
+
+- Bumped `py-ocsf-models` to 0.8.1 and `cryptography` to 44.0.3 [(#10059)](https://github.com/prowler-cloud/prowler/pull/10059)
+
+---
+
+## [5.18.3] (Prowler UNRELEASED)
+
+### 🐞 Fixed
+
+- `pip install prowler` failing on systems without C compiler due to `netifaces` transitive dependency from `openstacksdk` [(#10055)](https://github.com/prowler-cloud/prowler/pull/10055)
+- `kms_key_not_publicly_accessible` false negative for specific KMS actions (e.g., `kms:DescribeKey`, `kms:Decrypt`) with unrestricted principals [(#10071)](https://github.com/prowler-cloud/prowler/pull/10071)
+- Remove account_id and location for manual requirements in M365CIS [(#10105)](https://github.com/prowler-cloud/prowler/pull/10105)
+
+---
+
+## [5.18.2] (Prowler v5.18.2)
+
+### 🐞 Fixed
+
+- `--repository` and `--organization` flags combined interaction in GitHub provider, qualifying unqualified repository names with organization [(#10001)](https://github.com/prowler-cloud/prowler/pull/10001)
+- HPACK library logging tokens in debug mode for Azure, M365, and Cloudflare providers [(#10010)](https://github.com/prowler-cloud/prowler/pull/10010)
+
+### 🐞 Fixed
+
+- Use `defusedxml` in the Alibaba Cloud OSS service to prevent XXE vulnerabilities when parsing XML responses [(#9999)](https://github.com/prowler-cloud/prowler/pull/9999)
---
@@ -17,6 +79,7 @@ All notable changes to the **Prowler SDK** are documented in this file.
- `defender_zap_for_teams_enabled` check for M365 provider [(#9838)](https://github.com/prowler-cloud/prowler/pull/9838)
- `compute_instance_suspended_without_persistent_disks` check for GCP provider [(#9747)](https://github.com/prowler-cloud/prowler/pull/9747)
- `codebuild_project_webhook_filters_use_anchored_patterns` check for AWS provider to detect CodeBreach vulnerability [(#9840)](https://github.com/prowler-cloud/prowler/pull/9840)
+- `defender_atp_safe_attachments_policy_enabled` check for M365 provider [(#9837)](https://github.com/prowler-cloud/prowler/pull/9837)
- `exchange_shared_mailbox_sign_in_disabled` check for M365 provider [(#9828)](https://github.com/prowler-cloud/prowler/pull/9828)
- CloudTrail Timeline abstraction for querying resource modification history [(#9101)](https://github.com/prowler-cloud/prowler/pull/9101)
- Cloudflare `--account-id` filter argument [(#9894)](https://github.com/prowler-cloud/prowler/pull/9894)
@@ -25,6 +88,7 @@ All notable changes to the **Prowler SDK** are documented in this file.
- `OpenStack` documentation for the support in the CLI [(#9848)](https://github.com/prowler-cloud/prowler/pull/9848)
- Add HIPAA compliance framework for the Azure provider [(#9957)](https://github.com/prowler-cloud/prowler/pull/9957)
- Cloudflare provider credentials as constructor parameters (`api_token`, `api_key`, `api_email`) [(#9907)](https://github.com/prowler-cloud/prowler/pull/9907)
+- CIS 3.1 for the Oracle Cloud provider [(#9971)](https://github.com/prowler-cloud/prowler/pull/9971)
### 🔄 Changed
@@ -44,7 +108,7 @@ All notable changes to the **Prowler SDK** are documented in this file.
- Update Azure Network service metadata to new format [(#9624)](https://github.com/prowler-cloud/prowler/pull/9624)
- Update Azure Storage service metadata to new format [(#9628)](https://github.com/prowler-cloud/prowler/pull/9628)
-### 🐛 Fixed
+### 🐞 Fixed
- Duplicated findings in `entra_user_with_vm_access_has_mfa` check when user has multiple VM access roles [(#9914)](https://github.com/prowler-cloud/prowler/pull/9914)
- Jira integration failing with `INVALID_INPUT` error when sending findings with long resource UIDs exceeding 255-character summary limit [(#9926)](https://github.com/prowler-cloud/prowler/pull/9926)
@@ -112,6 +176,7 @@ All notable changes to the **Prowler SDK** are documented in this file.
- Update Azure AI Search service metadata to new format [(#9087)](https://github.com/prowler-cloud/prowler/pull/9087)
- Update Azure AKS service metadata to new format [(#9611)](https://github.com/prowler-cloud/prowler/pull/9611)
- Update Azure API Management service metadata to new format [(#9612)](https://github.com/prowler-cloud/prowler/pull/9612)
+- Enhance AWS IAM privilege escalation detection with patterns from pathfinding.cloud library [(#9922)](https://github.com/prowler-cloud/prowler/pull/9922)
### Fixed
diff --git a/prowler/__main__.py b/prowler/__main__.py
index fd7869193b..9fa9e91ad9 100644
--- a/prowler/__main__.py
+++ b/prowler/__main__.py
@@ -8,6 +8,7 @@ from colorama import Fore, Style
from colorama import init as colorama_init
from prowler.config.config import (
+ EXTERNAL_TOOL_PROVIDERS,
csv_file_suffix,
get_available_compliance_frameworks,
html_file_suffix,
@@ -65,6 +66,11 @@ from prowler.lib.outputs.compliance.cis.cis_kubernetes import KubernetesCIS
from prowler.lib.outputs.compliance.cis.cis_m365 import M365CIS
from prowler.lib.outputs.compliance.cis.cis_oraclecloud import OracleCloudCIS
from prowler.lib.outputs.compliance.compliance import display_compliance_table
+from prowler.lib.outputs.compliance.csa.csa_alibabacloud import AlibabaCloudCSA
+from prowler.lib.outputs.compliance.csa.csa_aws import AWSCSA
+from prowler.lib.outputs.compliance.csa.csa_azure import AzureCSA
+from prowler.lib.outputs.compliance.csa.csa_gcp import GCPCSA
+from prowler.lib.outputs.compliance.csa.csa_oraclecloud import OracleCloudCSA
from prowler.lib.outputs.compliance.ens.ens_aws import AWSENS
from prowler.lib.outputs.compliance.ens.ens_azure import AzureENS
from prowler.lib.outputs.compliance.ens.ens_gcp import GCPENS
@@ -119,6 +125,8 @@ from prowler.providers.common.quick_inventory import run_provider_quick_inventor
from prowler.providers.gcp.models import GCPOutputOptions
from prowler.providers.github.models import GithubOutputOptions
from prowler.providers.iac.models import IACOutputOptions
+from prowler.providers.image.exceptions.exceptions import ImageBaseException
+from prowler.providers.image.models import ImageOutputOptions
from prowler.providers.kubernetes.models import KubernetesOutputOptions
from prowler.providers.llm.models import LLMOutputOptions
from prowler.providers.m365.models import M365OutputOptions
@@ -206,8 +214,8 @@ def prowler():
# Load compliance frameworks
logger.debug("Loading compliance frameworks from .json files")
- # Skip compliance frameworks for IAC and LLM providers
- if provider != "iac" and provider != "llm":
+ # Skip compliance frameworks for external-tool providers
+ if provider not in EXTERNAL_TOOL_PROVIDERS:
bulk_compliance_frameworks = Compliance.get_bulk(provider)
# Complete checks metadata with the compliance framework specification
bulk_checks_metadata = update_checks_metadata_with_compliance(
@@ -264,8 +272,8 @@ def prowler():
if not args.only_logs:
global_provider.print_credentials()
- # Skip service and check loading for IAC and LLM providers
- if provider != "iac" and provider != "llm":
+ # Skip service and check loading for external-tool providers
+ if provider not in EXTERNAL_TOOL_PROVIDERS:
# Import custom checks from folder
if checks_folder:
custom_checks = parse_checks_from_folder(global_provider, checks_folder)
@@ -352,6 +360,8 @@ def prowler():
)
elif provider == "iac":
output_options = IACOutputOptions(args, bulk_checks_metadata)
+ elif provider == "image":
+ output_options = ImageOutputOptions(args, bulk_checks_metadata)
elif provider == "llm":
output_options = LLMOutputOptions(args, bulk_checks_metadata)
elif provider == "oraclecloud":
@@ -375,8 +385,8 @@ def prowler():
# Execute checks
findings = []
- if provider == "iac" or provider == "llm":
- # For IAC and LLM providers, run the scan directly
+ if provider in EXTERNAL_TOOL_PROVIDERS:
+ # For external-tool providers, run the scan directly
if provider == "llm":
def streaming_callback(findings_batch):
@@ -386,7 +396,11 @@ def prowler():
findings = global_provider.run_scan(streaming_callback=streaming_callback)
else:
# Original behavior for IAC or non-verbose LLM
- findings = global_provider.run()
+ try:
+ findings = global_provider.run()
+ except ImageBaseException as error:
+ logger.critical(f"{error}")
+ sys.exit(1)
# Note: IaC doesn't support granular progress tracking since Trivy runs as a black box
# and returns all findings at once. Progress tracking would just be 0% → 100%.
@@ -626,6 +640,18 @@ def prowler():
)
generated_outputs["compliance"].append(c5)
c5.batch_write_data_to_file()
+ elif compliance_name == "csa_ccm_4.0_aws":
+ filename = (
+ f"{output_options.output_directory}/compliance/"
+ f"{output_options.output_filename}_{compliance_name}.csv"
+ )
+ csa_ccm_4_0_aws = AWSCSA(
+ findings=finding_outputs,
+ compliance=bulk_compliance_frameworks[compliance_name],
+ file_path=filename,
+ )
+ generated_outputs["compliance"].append(csa_ccm_4_0_aws)
+ csa_ccm_4_0_aws.batch_write_data_to_file()
else:
filename = (
f"{output_options.output_directory}/compliance/"
@@ -729,6 +755,18 @@ def prowler():
)
generated_outputs["compliance"].append(c5_azure)
c5_azure.batch_write_data_to_file()
+ elif compliance_name == "csa_ccm_4.0_azure":
+ filename = (
+ f"{output_options.output_directory}/compliance/"
+ f"{output_options.output_filename}_{compliance_name}.csv"
+ )
+ csa_ccm_4_0_azure = AzureCSA(
+ findings=finding_outputs,
+ compliance=bulk_compliance_frameworks[compliance_name],
+ file_path=filename,
+ )
+ generated_outputs["compliance"].append(csa_ccm_4_0_azure)
+ csa_ccm_4_0_azure.batch_write_data_to_file()
else:
filename = (
f"{output_options.output_directory}/compliance/"
@@ -832,6 +870,18 @@ def prowler():
)
generated_outputs["compliance"].append(c5_gcp)
c5_gcp.batch_write_data_to_file()
+ elif compliance_name == "csa_ccm_4.0_gcp":
+ filename = (
+ f"{output_options.output_directory}/compliance/"
+ f"{output_options.output_filename}_{compliance_name}.csv"
+ )
+ csa_ccm_4_0_gcp = GCPCSA(
+ findings=finding_outputs,
+ compliance=bulk_compliance_frameworks[compliance_name],
+ file_path=filename,
+ )
+ generated_outputs["compliance"].append(csa_ccm_4_0_gcp)
+ csa_ccm_4_0_gcp.batch_write_data_to_file()
else:
filename = (
f"{output_options.output_directory}/compliance/"
@@ -1024,6 +1074,18 @@ def prowler():
)
generated_outputs["compliance"].append(cis)
cis.batch_write_data_to_file()
+ elif compliance_name == "csa_ccm_4.0_oraclecloud":
+ filename = (
+ f"{output_options.output_directory}/compliance/"
+ f"{output_options.output_filename}_{compliance_name}.csv"
+ )
+ csa_ccm_4_0_oraclecloud = OracleCloudCSA(
+ findings=finding_outputs,
+ compliance=bulk_compliance_frameworks[compliance_name],
+ file_path=filename,
+ )
+ generated_outputs["compliance"].append(csa_ccm_4_0_oraclecloud)
+ csa_ccm_4_0_oraclecloud.batch_write_data_to_file()
else:
filename = (
f"{output_options.output_directory}/compliance/"
@@ -1052,6 +1114,18 @@ def prowler():
)
generated_outputs["compliance"].append(cis)
cis.batch_write_data_to_file()
+ elif compliance_name == "csa_ccm_4.0_alibabacloud":
+ filename = (
+ f"{output_options.output_directory}/compliance/"
+ f"{output_options.output_filename}_{compliance_name}.csv"
+ )
+ csa_ccm_4_0_alibabacloud = AlibabaCloudCSA(
+ findings=finding_outputs,
+ compliance=bulk_compliance_frameworks[compliance_name],
+ file_path=filename,
+ )
+ generated_outputs["compliance"].append(csa_ccm_4_0_alibabacloud)
+ csa_ccm_4_0_alibabacloud.batch_write_data_to_file()
elif compliance_name == "prowler_threatscore_alibabacloud":
filename = (
f"{output_options.output_directory}/compliance/"
diff --git a/prowler/compliance/alibabacloud/csa_ccm_4.0_alibabacloud.json b/prowler/compliance/alibabacloud/csa_ccm_4.0_alibabacloud.json
new file mode 100644
index 0000000000..060b6e819e
--- /dev/null
+++ b/prowler/compliance/alibabacloud/csa_ccm_4.0_alibabacloud.json
@@ -0,0 +1,7305 @@
+{
+ "Framework": "CSA-CCM",
+ "Name": "CSA Cloud Controls Matrix (CCM) v4.0.13",
+ "Version": "4.0",
+ "Provider": "alibabacloud",
+ "Description": "The Cloud Security Alliance (CSA) Cloud Controls Matrix (CCM) is a cybersecurity control framework for cloud computing, composed of 197 control objectives structured in 17 domains covering all key aspects of cloud technology. The CCM can be used as a tool for the systematic assessment of a cloud implementation, and provides guidance on which security controls should be implemented by which actor within the cloud supply chain.",
+ "Requirements": [
+ {
+ "Id": "A&A-02",
+ "Description": "Conduct independent audit and assurance assessments according to relevant standards at least annually.",
+ "Name": "Independent Assessments",
+ "Attributes": [
+ {
+ "Section": "Audit & Assurance",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC4.1"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "AAC-02"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "1.5.2",
+ "5.2.6"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "AS1.1",
+ "AS2.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.18.2.1",
+ "27002: 18.2.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.35",
+ "27001: A.5.36"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "CA-2",
+ "CA-2(1)",
+ "CA-2(2)",
+ "CA-7",
+ "CA-7(1)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "ID.IM-01"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "securitycenter_advanced_or_enterprise_edition"
+ ]
+ },
+ {
+ "Id": "A&A-04",
+ "Description": "Verify compliance with all relevant standards, regulations, legal/contractual, and statutory requirements applicable to the audit.",
+ "Name": "Requirements Compliance",
+ "Attributes": [
+ {
+ "Section": "Audit & Assurance",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC3.1"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "GRM-01",
+ "GRM-03"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "7.1.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "AS1.1",
+ "AS2.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: 9.3.2",
+ "27001: A.18.2.2",
+ "27002: 18.2.2",
+ "27001: A.18.2.3",
+ "27002: 18.2.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: 9.3.2",
+ "27001: A.5.31",
+ "27001: A.5.32",
+ "27001: A.5.33",
+ "27001: A.5.34",
+ "27001: A.5.36"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "CA-1"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "ID.GV-3",
+ "DE.DP-2"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "ID.IM-01"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "securitycenter_advanced_or_enterprise_edition"
+ ]
+ },
+ {
+ "Id": "AIS-04",
+ "Description": "Define and implement a SDLC process for application design, development, deployment, and operation in accordance with security requirements defined by the organization.",
+ "Name": "Secure Application Design and Development",
+ "Attributes": [
+ {
+ "Section": "Application & Interface Security",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "CSP-Owned",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC6.8",
+ "CC8.1"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "AIS-01",
+ "AIS-03"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "16.1"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "1.3.4",
+ "5.3.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "SD1.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.14.1.1",
+ "27002: 14.1.1",
+ "27017: 14.1.1",
+ "27001: A.14.1.2",
+ "27002: 14.1.2",
+ "27017: 14.1.2",
+ "27001: A.14.2.1",
+ "27002: 14.2.1",
+ "27017: 14.2.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.8",
+ "27001: A.8.25",
+ "27001: A.8.26",
+ "27001: A.8.28"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "PL-2",
+ "PL-8",
+ "PL-8(1)",
+ "SA-3",
+ "SA-3(1)",
+ "SA-4",
+ "SA-4(2)",
+ "SA-4(3)",
+ "SA-4(8)",
+ "SA-4(9)",
+ "SA-5",
+ "SA-8",
+ "SA-8(1)-(7)",
+ "SA-8(9)-(13)",
+ "SA-8(15)-(20)",
+ "SA-8(22)",
+ "SA-8(24)-(28)",
+ "SA-8(30)-(33)",
+ "SA-17",
+ "SA-17(1)-(9)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.DS-6",
+ "PR.DS-7",
+ "PR.IP-2"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "ID.AM-08",
+ "PR.IR-01",
+ "PR.PS-01",
+ "PR.PS-02",
+ "PR.PS-06"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "6.3"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "6.2.1",
+ "6.2.3",
+ "6.5.2"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": []
+ },
+ {
+ "Id": "AIS-05",
+ "Description": "Implement a testing strategy, including criteria for acceptance of new information systems, upgrades and new versions, which provides application security assurance and maintains compliance while enabling organizational speed of delivery goals. Automate when applicable and possible.",
+ "Name": "Automated Application Security Testing",
+ "Attributes": [
+ {
+ "Section": "Application & Interface Security",
+ "CCMLite": "No",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC6.8",
+ "CC8.1"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "AIS-01",
+ "AIS-03"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "16.12",
+ "16.13"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "SD2.3",
+ "SD2.5"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.14.2.8",
+ "27001: A.14.2.9",
+ "27001: A.12.1.2",
+ "27002: 12.1.2",
+ "27001: A.14.1.1",
+ "27002: 14.1.1",
+ "27001: A.14.2.2",
+ "27002: 14.2.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.8.25",
+ "27001: A.8.29",
+ "27001: A.8.32",
+ "27002: 8.25 (e)",
+ "27002: 8.32 (d)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "SA-11",
+ "SA-11(1)-(9)",
+ "SI-6",
+ "SI-6(2)",
+ "SI-6(3)",
+ "SI-10",
+ "SI-10(1)-(6)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.IP-2",
+ "PR.PT-3",
+ "PR.IP-12",
+ "DE.CM-8"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "ID.AM-08",
+ "ID.RA-01",
+ "PR.PS-01",
+ "PR.PS-02"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "A.3.2.2",
+ "A.3.2.2.1",
+ "6.6"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "6.2.4",
+ "6.4.1",
+ "6.4.2",
+ "6.5.1"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "securitycenter_vulnerability_scan_enabled"
+ ]
+ },
+ {
+ "Id": "AIS-07",
+ "Description": "Define and implement a process to remediate application security vulnerabilities, automating remediation when possible.",
+ "Name": "Application Vulnerability Remediation",
+ "Attributes": [
+ {
+ "Section": "Application & Interface Security",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC7.1",
+ "CC7.4",
+ "CC8.1"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "TVM-02"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "16.2",
+ "16.6"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "TM1.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.16.1.5",
+ "27002: 16.1.5",
+ "27017: 16.1.5",
+ "27001: A.12.6.1",
+ "27002: 12.6.1",
+ "27017: 12.6.1",
+ "27018: 12.6.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.26",
+ "27001: A.8.8",
+ "27002: 5.26 (j)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "SI-2",
+ "SI-2(2)-(6)",
+ "SA-11",
+ "SA-11(2)",
+ "SA-15",
+ "SA-15(1)-(3)",
+ "SA-15(5)-(8)",
+ "SA-15(10)-(12)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.IP-2",
+ "PR.IP-12",
+ "DE.CM-8",
+ "RS.AN-5",
+ "RS.MI-3",
+ "PR.DS-6"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "ID.AM-08",
+ "ID.RA-01",
+ "ID.RA-06",
+ "ID.RA-08",
+ "PR.PS-02",
+ "PR.PS-06"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "6.2",
+ "6.5",
+ "6.5.1-10"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "6.3.1",
+ "11.3.1",
+ "11.3.1.1"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "securitycenter_vulnerability_scan_enabled"
+ ]
+ },
+ {
+ "Id": "BCR-08",
+ "Description": "Periodically backup data stored in the cloud. Ensure the confidentiality, integrity and availability of the backup, and verify data restoration from backup for resiliency.",
+ "Name": "Backup",
+ "Attributes": [
+ {
+ "Section": "Business Continuity Management and Operational Resilience",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "A1.2",
+ "A1.3"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "BCR-11"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "11.1",
+ "11.2",
+ "11.3",
+ "11.4",
+ "11.5"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.2.8",
+ "5.2.9"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "SY2.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.12.3",
+ "27017: 12.3",
+ "27018: 12.3.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.8.13",
+ "27001: A.5.23",
+ "27001: A.5.30",
+ "27002: 8.13",
+ "27002: 5.23 2nd (i)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "CP-4",
+ "CP-4(4)",
+ "CP-6",
+ "CP-6(1)-(3)",
+ "CP-9",
+ "CP-9(1)",
+ "CP-9(2)",
+ "CP-10",
+ "CP-10(2)",
+ "CP-10(4)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.IP-4",
+ "PR.DS-1"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.DS-01",
+ "PR.DS-11",
+ "RC.RP-03"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "9.5.1",
+ "12.10.1"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "12.10.1",
+ "10.3.3"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": []
+ },
+ {
+ "Id": "BCR-09",
+ "Description": "Establish, document, approve, communicate, apply, evaluate and maintain a disaster response plan to recover from natural and man-made disasters. Update the plan at least annually or upon significant changes.",
+ "Name": "Disaster Response Plan",
+ "Attributes": [
+ {
+ "Section": "Business Continuity Management and Operational Resilience",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "A1.2",
+ "CC3.2"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.2.8",
+ "5.2.9",
+ "1.6.1",
+ "1.6.2",
+ "1.6.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "BC1.4",
+ "BC2.1",
+ "BC2.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.29",
+ "27001: A.5.30",
+ "27002: 5.29",
+ "27002: 5.30"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "CP-2(1)",
+ "CP-2(2)",
+ "CP-2(3)",
+ "CP-2(5)",
+ "CP-2(6)",
+ "CP-2(7)",
+ "CP-2(8)",
+ "PE-13",
+ "PE-13(1)",
+ "PE-13(2)",
+ "PE-13(4)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.IP-9",
+ "PR.IP-10",
+ "RC.IM-1",
+ "RC.IM-2"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "ID.IM-04"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": []
+ },
+ {
+ "Id": "BCR-11",
+ "Description": "Supplement business-critical equipment with redundant equipment independently located at a reasonable minimum distance in accordance with applicable industry standards.",
+ "Name": "Equipment Redundancy",
+ "Attributes": [
+ {
+ "Section": "Business Continuity Management and Operational Resilience",
+ "CCMLite": "No",
+ "IaaS": "CSP-Owned",
+ "PaaS": "CSP-Owned",
+ "SaaS": "CSP-Owned",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "A1.2",
+ "CC3.2"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "BCR-06"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.2.8"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "BC1.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.20",
+ "27001: A.7.11",
+ "27001: A.8.14",
+ "27002: 5.20 (t)",
+ "27002: 8.14 (c)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "CP-2",
+ "CP-2(2)",
+ "CP-4(3)",
+ "CP-6",
+ "CP-6(1)",
+ "CP-7",
+ "CP-8",
+ "CP-8(1)-(3)",
+ "CP-9",
+ "CP-9(6)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "ID.BE-4",
+ "ID.BE-5"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "GV.OC-04",
+ "GV.OC-05",
+ "PR.IR-03"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": []
+ },
+ {
+ "Id": "CCC-04",
+ "Description": "Restrict the unauthorized addition, removal, update, and management of organization assets.",
+ "Name": "Unauthorized Change Protection",
+ "Attributes": [
+ {
+ "Section": "Change Control and Configuration Management",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC8.1"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "CCC-04"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.2.1",
+ "1.3.4",
+ "5.3.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "SY2.4",
+ "SM2.6"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.12.1.4",
+ "27002: 12.1.4",
+ "27001: A.12.4.2",
+ "27002: 12.4.2",
+ "27001: A.14.2.2",
+ "27017: 14.2.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.8.3",
+ "27001: A.8.4",
+ "27001: A.8.15",
+ "27001: A.8.31",
+ "27001: A.8.32"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "CA-7",
+ "CA-7(4)",
+ "CM-3",
+ "CM-3(1)",
+ "CM-3(5)",
+ "CM-3(7)",
+ "CM-3(8)",
+ "CM-5",
+ "CM-5(1)",
+ "CM-5(4)",
+ "CM-5(5)",
+ "CM-6",
+ "CM-6(1)",
+ "CM-6(2)",
+ "CM-7",
+ "CM-7(1)",
+ "CM-7(4)",
+ "CM-7(5)",
+ "CM-7(9)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "ID.AM-1",
+ "ID.AM-2",
+ "ID.AM-4",
+ "PR.MA-1",
+ "PR.MA-2",
+ "PR.AC-1"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "ID.AM-01",
+ "ID.AM-02",
+ "ID.AM-04",
+ "ID.AM-08",
+ "PR.PS-02",
+ "PR.PS-03",
+ "PR.PS-05",
+ "PR.AA-05"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "6.4.5.2"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "6.5.1",
+ "6.5.2"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "actiontrail_multi_region_enabled"
+ ]
+ },
+ {
+ "Id": "CCC-07",
+ "Description": "Implement detection measures with proactive notification in case of changes deviating from the established baseline.",
+ "Name": "Detection of Baseline Deviation",
+ "Attributes": [
+ {
+ "Section": "Change Control and Configuration Management",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC8.1"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "GRM-01"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "1.5.1",
+ "1.5.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "SY2.4"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.14.2.2",
+ "27001: A.14.2.4",
+ "27001: A.12.4.1",
+ "27002: 12.4.1 (g)",
+ "27001: A.5.1.1",
+ "27017: 5.1.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.8.9",
+ "27001: A.8.15",
+ "27002: 8.9"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "CM-6",
+ "CM-6(2)",
+ "SI-2",
+ "SI-2(2)-(6)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.MA-1",
+ "PR.IP-1",
+ "DE.DP-4",
+ "PR.IP-3"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.PS-01",
+ "DE.CM-09",
+ "DE.AE-06"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "6.4.5.3",
+ "6.4.5.4",
+ "11.5",
+ "11.5.1"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "11.5.2",
+ "11.6.1"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "securitycenter_advanced_or_enterprise_edition",
+ "sls_security_group_changes_alert_enabled",
+ "sls_vpc_changes_alert_enabled",
+ "sls_vpc_network_route_changes_alert_enabled",
+ "sls_customer_created_cmk_changes_alert_enabled",
+ "sls_cloud_firewall_changes_alert_enabled",
+ "sls_management_console_authentication_failures_alert_enabled",
+ "sls_rds_instance_configuration_changes_alert_enabled"
+ ]
+ },
+ {
+ "Id": "CEK-03",
+ "Description": "Provide cryptographic protection to data at-rest and in-transit, using cryptographic libraries certified to approved standards.",
+ "Name": "Data Encryption",
+ "Attributes": [
+ {
+ "Section": "Cryptography, Encryption & Key Management",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC6.1",
+ "CC6.7"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "EKM-03",
+ "EKM-04"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "3.6",
+ "3.1",
+ "3.11",
+ "11.3",
+ "16.11"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.1.1",
+ "5.1.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "TS2.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.18.1.1",
+ "27001: A.18.1.2",
+ "27001: A.18.1.3",
+ "27001: A.18.1.4",
+ "27001: A.18.1.5",
+ "27001: A.10.1",
+ "27002: 10.1",
+ "27001: A.13.2.1",
+ "27002: 13.2.1",
+ "27001: A.18",
+ "27002: 18",
+ "27001: A.14.1.2",
+ "27002: 14.1.2",
+ "27001: A.14.1.3",
+ "27002 14.1.3 c)",
+ "27001 - A.10.1.1",
+ "27017 - 10.1.1",
+ "27001 - A.10.1.2",
+ "27017 - 10.1.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.14",
+ "27001: A.8.24",
+ "27002: 8.24 Other Information (a)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "AC-19",
+ "AC-19(5)",
+ "SC-8",
+ "SC-8(1)",
+ "SC-8(3)",
+ "SC-8(4)",
+ "SC-12",
+ "SC-12(2)",
+ "SC-12(3)",
+ "SC-28",
+ "SC-28(1)-(3)",
+ "SI-4",
+ "SI-4(10)",
+ "SI-7",
+ "SI-7(6)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.DS-1",
+ "PR.DS-2"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.DS-01",
+ "PR.DS-02"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "Requirement 3",
+ "2.2.3",
+ "2.3",
+ "3.4",
+ "3.5.3",
+ "4.1",
+ "8.2.1",
+ "PCI Glossary - Strong Cryptography"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "2.2.7",
+ "3.5.1",
+ "4.2.1",
+ "4.2.1.2",
+ "4.2.2"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "ecs_attached_disk_encrypted",
+ "ecs_unattached_disk_encrypted",
+ "rds_instance_tde_enabled",
+ "rds_instance_ssl_enabled",
+ "oss_bucket_secure_transport_enabled"
+ ]
+ },
+ {
+ "Id": "CEK-04",
+ "Description": "Use encryption algorithms that are appropriate for data protection, considering the classification of data, associated risks, and usability of the encryption technology.",
+ "Name": "Encryption Algorithm",
+ "Attributes": [
+ {
+ "Section": "Cryptography, Encryption & Key Management",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC6.1",
+ "CC6.7"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "EKM-04"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "16.11"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.1.1",
+ "5.1.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "TS2.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: 6.1.2",
+ "27001: 6.1.3",
+ "27001: A.8.2",
+ "27002: 8.2",
+ "27001: A.8.3",
+ "27001: A.10.1.1",
+ "27002: 10.1.1 (b)",
+ "27001: A.10.1.2",
+ "27002: 10.1.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: 6.1.2",
+ "27001: 6.1.3",
+ "27001: A.8.24",
+ "27001: A.5.12",
+ "27001: A.5.13",
+ "27002: 8.24 General (b)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "SC-12",
+ "SC-12(2)",
+ "SC-12(3)",
+ "SC-28",
+ "SC-28(1)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.DS-1",
+ "PR.DS-2",
+ "ID.AM-5"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.DS-01",
+ "PR.DS-02",
+ "ID.AM-05"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "A2",
+ "Requirement 3",
+ "2.3",
+ "2.2.3",
+ "3.4",
+ "3.5.3",
+ "4.1",
+ "8.2.1",
+ "PCI Glossary - Strong Cryptography"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "2.2.7",
+ "3.5.1",
+ "4.2.1",
+ "4.2.1.2",
+ "4.2.2"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": []
+ },
+ {
+ "Id": "CEK-08",
+ "Description": "CSPs must provide the capability for CSCs to manage their own data encryption keys.",
+ "Name": "CSC Key Management Capability",
+ "Attributes": [
+ {
+ "Section": "Cryptography, Encryption & Key Management",
+ "CCMLite": "No",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "TS2.2",
+ "SC2.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.10.1",
+ "27017: 10.1",
+ "27001: A.10.1.1",
+ "27017: 10.1.1",
+ "27001: A.10.1.2",
+ "27017: 10.1.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.23",
+ "27001: A.8.24"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "CP-9",
+ "CP-9(8)",
+ "SA-9",
+ "SA-9(6)",
+ "SC-12",
+ "SC-12(6)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "ID.SC-3",
+ "ID.AM-6",
+ "PR.AC-1"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "GV.SC-05"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "rds_instance_tde_key_custom"
+ ]
+ },
+ {
+ "Id": "CEK-10",
+ "Description": "Generate Cryptographic keys using industry accepted cryptographic libraries specifying the algorithm strength and the random number generator used.",
+ "Name": "Key Generation",
+ "Attributes": [
+ {
+ "Section": "Cryptography, Encryption & Key Management",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "EKM-04"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "16.11"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.1.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "TS2.2",
+ "TS2.3",
+ "SY1.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.10.1.1",
+ "27002: 10.1.1 (e)",
+ "27017: 10.1.1",
+ "27001: A.10.1.2",
+ "27002: 10.1.2",
+ "27002: 10.1.2 (a)",
+ "27017: 10.1.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.8.24",
+ "27002: 8.24 (d), Key management (a)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "SC-12",
+ "SC-12(2)",
+ "SC-12(3)",
+ "SC-13"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.AC-1"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.AA-01",
+ "PR.AA-05"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "2.2.3",
+ "3.6.1",
+ "PCI Glossary - Cryptographic Key Generation"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "3.6.1",
+ "3.6.1.1",
+ "3.7.1"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "rds_instance_tde_key_custom"
+ ]
+ },
+ {
+ "Id": "CEK-12",
+ "Description": "Rotate cryptographic keys in accordance with the calculated cryptoperiod, which includes provisions for considering the risk of information disclosure and legal and regulatory requirements.",
+ "Name": "Key Rotation",
+ "Attributes": [
+ {
+ "Section": "Cryptography, Encryption & Key Management",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.1.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "TS2.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.10.1.1",
+ "27017: 10.1.1",
+ "27001: A.10.1.2",
+ "27002: 10.1.2 e)",
+ "27017: 10.1.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.31",
+ "27001: A.8.24",
+ "27002: 5.31 Cryptography",
+ "27002: 8.24 Key management (e,m)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "SC-12",
+ "SC-12(2)",
+ "SC-12(3)",
+ "SC-13"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.AC-1",
+ "ID.GV-3"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.AA-01",
+ "PR.AA-05",
+ "GV.OC-03"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "3.7.4",
+ "3.7.5"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "ram_rotate_access_key_90_days"
+ ]
+ },
+ {
+ "Id": "CEK-14",
+ "Description": "Define, implement and evaluate processes, procedures and technical measures to destroy keys stored outside a secure environment and revoke keys stored in Hardware Security Modules (HSMs) when they are no longer needed, which include provisions for legal and regulatory requirements.",
+ "Name": "Key Destruction",
+ "Attributes": [
+ {
+ "Section": "Cryptography, Encryption & Key Management",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.1.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "TS2.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.10.1.1",
+ "27017: 10.1.1",
+ "27017: 10.1.2",
+ "27001: A.10.1.2",
+ "27002: 10.1.2 (j)",
+ "27001: A.18.1.3",
+ "27002: 18.1.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.31",
+ "27001: A.8.24",
+ "27002: 5.31 Cryptography",
+ "27002: 8.24 Key management (j,m)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "SC-12",
+ "SC-12(2)",
+ "SC-12(3)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.AC-1",
+ "PR.IP-6",
+ "ID.GV-3",
+ "PR.DS-3"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.AA-01",
+ "PR.AA-05",
+ "ID.AM-08",
+ "GV.OC-03"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "3.6.4",
+ "3.6.5"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "3.7.4",
+ "3.7.5"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": []
+ },
+ {
+ "Id": "DCS-06",
+ "Description": "Catalogue and track all relevant physical and logical assets located at all of the CSP's sites within a secured system.",
+ "Name": "Assets Cataloguing and Tracking",
+ "Attributes": [
+ {
+ "Section": "Datacenter Security",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC6.1"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "DCS - 01"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "1.1",
+ "2.1"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "1.3.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "SM2.6"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.8.1.1",
+ "27002: 8.1.1",
+ "27017: 8.1.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.9"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "CM-8",
+ "CM-8(1)",
+ "CM-8(2)",
+ "CM-8(4)",
+ "CM-8(7)",
+ "CM-8(8)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "ID.AM-1",
+ "ID.AM-2",
+ "ID.AM-4",
+ "PR.AC-4"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "ID.AM-01",
+ "ID.AM-02",
+ "ID.AM-04"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "2.4",
+ "9.7.1",
+ "9.9.1",
+ "9.9.1.a",
+ "9.9.1.b",
+ "9.9.1.c",
+ "12.3.3",
+ "12.3.4"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "3.6.1.1",
+ "6.3.2",
+ "9.4.2",
+ "9.4.3",
+ "12.5.1"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "securitycenter_all_assets_agent_installed"
+ ]
+ },
+ {
+ "Id": "DSP-02",
+ "Description": "Apply industry accepted methods for the secure disposal of data from storage media such that data is not recoverable by any forensic means.",
+ "Name": "Secure Disposal",
+ "Attributes": [
+ {
+ "Section": "Data Security and Privacy Lifecycle Management",
+ "CCMLite": "No",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC6.1",
+ "CC6.2",
+ "CC6.3",
+ "CC6.4",
+ "CC6.5",
+ "CC6.7",
+ "P4.3"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "DSI-07"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "3.5"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.1.1",
+ "5.3.3",
+ "7.1.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "IM1.1",
+ "IM1.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.8.3.2",
+ "27002: 8.3.2",
+ "27001: A.11.2.7",
+ "27002: 11.2.7"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.7.10",
+ "27001: A.7.14",
+ "27001: A.8.10",
+ "27002: 7.10 (Secure reuse or disposal)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "PM-22",
+ "SI-12",
+ "SI-12(3)",
+ "SI-18",
+ "SI-18(1)",
+ "SI-18(4)",
+ "SI-18(5)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.IP-6"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "GV.SC-10",
+ "PR.PS-02",
+ "PR.PS-03",
+ "ID.AM-08"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "3.1",
+ "9.8",
+ "9.8.1",
+ "9.8.2"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "3.2.1",
+ "3.7.5",
+ "9.4.7"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": []
+ },
+ {
+ "Id": "DSP-03",
+ "Description": "Create and maintain a data inventory, at least for any sensitive data and personal data.",
+ "Name": "Data Inventory",
+ "Attributes": [
+ {
+ "Section": "Data Security and Privacy Lifecycle Management",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC6.1"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "3.2"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "1.3.1",
+ "1.3.2",
+ "1.3.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "IM1.1",
+ "IM2.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.8.1.1",
+ "27002: 8.1.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.9",
+ "27001: A.8.12"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "CM-12",
+ "CM-12(1)",
+ "PM-5",
+ "PM-5(1)",
+ "SI-12",
+ "SI-12(1)",
+ "SI-19",
+ "SI-19(1)",
+ "SI-19(2)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "ID.AM-5"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "ID.AM-07"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "3.2.1",
+ "9.4.5"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "securitycenter_all_assets_agent_installed"
+ ]
+ },
+ {
+ "Id": "DSP-04",
+ "Description": "Classify data according to its type and sensitivity level.",
+ "Name": "Data Classification",
+ "Attributes": [
+ {
+ "Section": "Data Security and Privacy Lifecycle Management",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC6.1",
+ "C1.1"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "DSI-01"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "3.7"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "1.3.1",
+ "1.3.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "IM1.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.8.2.1",
+ "27002: 8.2.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.12"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "AC-16",
+ "AC-16(9)",
+ "PM-22",
+ "PM-23",
+ "PT-2",
+ "PT-2(1)",
+ "SI-18",
+ "SI-18(2)",
+ "SI-19",
+ "SI-19(6)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "ID.AM-5"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "ID.AM-05",
+ "ID.AM-07"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "9.6.1"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "9.4.2",
+ "9.4.3"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": []
+ },
+ {
+ "Id": "DSP-07",
+ "Description": "Develop systems, products, and business practices based upon a principle of security by design and industry best practices.",
+ "Name": "Data Protection by Design and Default",
+ "Attributes": [
+ {
+ "Section": "Data Security and Privacy Lifecycle Management",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "PI1.2",
+ "PI1.3"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "16.1"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.3.1",
+ "5.3.2",
+ "5.3.3",
+ "5.3.4"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "SD2.2",
+ "IM1.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.14.1.1",
+ "27002:14.1.1",
+ "27001: A.14.2.5",
+ "27002:14.2.5"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.8.27",
+ "27001: A.8.28",
+ "27001: A.8.29",
+ "27002: 5.8 (Information security requirements a-i)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "PM-17",
+ "PM-24",
+ "PM-25",
+ "PT-2",
+ "PT-2(2)",
+ "SA-3",
+ "SA-4",
+ "SA-5",
+ "SA-8",
+ "SA-8(9)",
+ "SA-8(13)",
+ "SA-8(18)",
+ "SA-8(20)",
+ "SA-8(22)",
+ "SA-8(23)",
+ "SA-8(33)",
+ "SA-15",
+ "SA-15(12)",
+ "SC-3",
+ "SC-3(3)",
+ "SC-7",
+ "SC-7(24)",
+ "SC-8",
+ "SC-8(1)-(4)",
+ "SC-28",
+ "SC-28(1)",
+ "SI-12",
+ "SI-12(1)-(3)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.IP-2",
+ "PR.PT-3",
+ "PR.AC-4"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "ID.AM-08",
+ "PR.PS-06"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "6.2.1"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "oss_bucket_not_publicly_accessible",
+ "rds_instance_no_public_access_whitelist"
+ ]
+ },
+ {
+ "Id": "DSP-10",
+ "Description": "Define, implement and evaluate processes, procedures and technical measures that ensure any transfer of personal or sensitive data is protected from unauthorized access and only processed within scope as permitted by the respective laws and regulations.",
+ "Name": "Sensitive Data Transfer",
+ "Attributes": [
+ {
+ "Section": "Data Security and Privacy Lifecycle Management",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC6.7"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "GRM-02",
+ "EKM-03"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "3.1",
+ "3.12",
+ "3.13"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.1.2",
+ "9.5.1",
+ "9.5.2",
+ "9.5.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "IM1.4",
+ "IM2.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.13.2.1",
+ "27002: 13.2.1",
+ "27001: A.8.3.3",
+ "27002: 8.3.3",
+ "27001: A.13.2.3",
+ "27002: 13.2.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.14",
+ "27001: A.7.10"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "AC-4",
+ "AC-4(23)-(25)",
+ "CA-3",
+ "CA-3(6)",
+ "CA-6",
+ "CA-6(1)",
+ "CA-6(2)",
+ "SC-4",
+ "SC-4(2)",
+ "SC-7",
+ "SC-7(10)",
+ "SC-7(24)",
+ "SC-8",
+ "SC-8(1)-(5)",
+ "SC-16",
+ "SC-16(1)-(3)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.DS-2",
+ "PR.DS-5",
+ "PR.PT-4"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.DS-02",
+ "PR.IR-01",
+ "ID.AM-03",
+ "GV.OC-03",
+ "ID.AM-07"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "4.1"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "4.1.1",
+ "4.2.1",
+ "4.2.2"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "oss_bucket_secure_transport_enabled",
+ "rds_instance_ssl_enabled"
+ ]
+ },
+ {
+ "Id": "DSP-16",
+ "Description": "Data retention, archiving and deletion is managed in accordance with business requirements, applicable laws and regulations.",
+ "Name": "Data Retention and Deletion",
+ "Attributes": [
+ {
+ "Section": "Data Security and Privacy Lifecycle Management",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "C1.1",
+ "C1.2",
+ "CC3.1",
+ "P4.2"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "GRM-02",
+ "BCR-11"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "3.4",
+ "3.5"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.1.1",
+ "5.3.1",
+ "7.1.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "IM1.1",
+ "IM2.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.18.1.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.33",
+ "27001: A.8.10",
+ "27002: 5.33 (b)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "SI-12",
+ "SI-12(1)-(3)",
+ "SI-18",
+ "SI-18(1)",
+ "SI-18(4)",
+ "SI-18(5)",
+ "SI-19",
+ "SI-19(2)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.DS-3",
+ "PR.IP-6",
+ "ID.GV-3"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "ID.AM-08",
+ "GV.OC-03",
+ "GV.SC-10",
+ "PR.DS-11"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "3.1"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "3.2.1"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "sls_logstore_retention_period",
+ "rds_instance_sql_audit_retention"
+ ]
+ },
+ {
+ "Id": "DSP-17",
+ "Description": "Define and implement, processes, procedures and technical measures to protect sensitive data throughout it's lifecycle.",
+ "Name": "Sensitive Data Protection",
+ "Attributes": [
+ {
+ "Section": "Data Security and Privacy Lifecycle Management",
+ "CCMLite": "Yes",
+ "IaaS": "CSP-Owned",
+ "PaaS": "CSP-Owned",
+ "SaaS": "CSC-Owned",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC2.1",
+ "CC6.1",
+ "CC6.3",
+ "CC6.7",
+ "CC8.1",
+ "C1.1",
+ "P2.0",
+ "P3.0",
+ "P4.0",
+ "P5.0",
+ "P6.0"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "3.1",
+ "3.1",
+ "3.14"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.3.3",
+ "9.1.1",
+ "9.2.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "IM1.1",
+ "IM2.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.18.1.3",
+ "27002: 18.1.3",
+ "27001:A.18.1.4",
+ "27002:18.1.4"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.8.11",
+ "27001: A.8.12"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "PL-2",
+ "PM-22",
+ "PM-24",
+ "PT-7",
+ "PT-7(1)",
+ "PT-7(2)",
+ "PT-8",
+ "SC-8",
+ "SC-8(1)-(5)",
+ "SC-28",
+ "SC-28(1)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.DS-1",
+ "PR.DS-2",
+ "PR.DS-5"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.DS-01",
+ "PR.DS-02",
+ "PR.DS-10"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "3.0 (including all subsections)",
+ "4.0 (including all subsections)"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "3.1.1",
+ "4.1.1"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "oss_bucket_not_publicly_accessible",
+ "rds_instance_no_public_access_whitelist",
+ "ecs_attached_disk_encrypted",
+ "ecs_unattached_disk_encrypted",
+ "rds_instance_tde_enabled"
+ ]
+ },
+ {
+ "Id": "GRC-05",
+ "Description": "Develop and implement an Information Security Program, which includes programs for all the relevant domains of the CCM.",
+ "Name": "Information Security Program",
+ "Attributes": [
+ {
+ "Section": "Governance, Risk and Compliance",
+ "CCMLite": "No",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "GRM-04"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "14.1"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "1.2.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "SG2.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: 4.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: 4.3"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "PM-1",
+ "PM-3",
+ "PM-14",
+ "PL-2",
+ "PM-18",
+ "PM-31"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "12.4.1",
+ "A.3.1"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "12.4.1",
+ "A3.1.1"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "securitycenter_advanced_or_enterprise_edition"
+ ]
+ },
+ {
+ "Id": "IAM-02",
+ "Description": "Establish, document, approve, communicate, implement, apply, evaluate and maintain strong password policies and procedures. Review and update the policies and procedures at least annually.",
+ "Name": "Strong Password Policy and Procedures",
+ "Attributes": [
+ {
+ "Section": "Identity & Access Management",
+ "CCMLite": "No",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "IAM-02",
+ "IAM-12",
+ "GRM-06",
+ "GRM-09"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "5.2"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "1.1.1",
+ "1.5.1",
+ "4.1.2",
+ "4.1.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "SA1.1",
+ "SA1.5"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: 5.1",
+ "27001: 5.2",
+ "27001: 7.3",
+ "27001: 7.4",
+ "27001: 7.5",
+ "27001: 9.1",
+ "27001: 9.3",
+ "27001: A.5",
+ "27002: 5",
+ "27001: A.9.4.3",
+ "27002: 9.4.3",
+ "27017: 9.4.3",
+ "27018: 9.4.3",
+ "27001: A.9.2.4",
+ "27002: 9.2.4",
+ "27017: 9.2.4",
+ "27001: A.7.2.2",
+ "27002: 7.2.2",
+ "27001: A.9.2.6",
+ "27002: 9.2.6",
+ "27001: A.9.2.3",
+ "27002: 9.2.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: 5.1",
+ "27001: 5.2",
+ "27001: 7.3",
+ "27001: 7.4",
+ "27001: 7.5",
+ "27001: 9.1",
+ "27001: 9.3",
+ "27001: A.5.1",
+ "27001: A.5.4",
+ "27001: A.5.17",
+ "27001: A.6.3",
+ "27001: A.8.5",
+ "27001: A.5.37"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "AC-2",
+ "AC-2(3)",
+ "AC-2(11)",
+ "AC-3",
+ "AC-3(3)",
+ "AC-12",
+ "AC-12(1)",
+ "IA-2",
+ "IA-2(10)",
+ "IA-5",
+ "IA-5(1)",
+ "IA-5(18)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "ID.GV-1",
+ "PR.AC-1",
+ "PR.AC-7"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "GV.PO-01",
+ "GV.PO-02",
+ "ID.IM-03",
+ "PR.AA-03"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "8.4",
+ "12.1",
+ "12.1.1",
+ "12.11"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "8.1.1",
+ "8.3.8"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "ram_password_policy_minimum_length",
+ "ram_password_policy_lowercase",
+ "ram_password_policy_uppercase",
+ "ram_password_policy_number",
+ "ram_password_policy_symbol",
+ "ram_password_policy_password_reuse_prevention",
+ "ram_password_policy_max_password_age",
+ "ram_password_policy_max_login_attempts"
+ ]
+ },
+ {
+ "Id": "IAM-03",
+ "Description": "Manage, store, and review the information of system identities, and level of access.",
+ "Name": "Identity Inventory",
+ "Attributes": [
+ {
+ "Section": "Identity & Access Management",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC6.1",
+ "CC6.3"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "IAM-04",
+ "IAM-08",
+ "IAM-10"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "5.1",
+ "5.2"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "4.1.3",
+ "4.2.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "SA1.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: 9.2 (c)",
+ "27001: A.8.1.1",
+ "27002: 8.1.1",
+ "27001: A.9.4.1",
+ "27002: 9.4.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: 9.2 (c)",
+ "27001: A.5.15",
+ "27001: A.5.16",
+ "27001: A.5.18",
+ "27001: A.7.4",
+ "27001: A.8.15",
+ "27001: A.8.2",
+ "27001: A.8.3"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "AU-10",
+ "AU-10(1)",
+ "AU-10(2)",
+ "AU-16",
+ "AU-16(1)",
+ "IA-4",
+ "IA-4(8)",
+ "IA-4(9)",
+ "IA-5",
+ "IA-5(5)",
+ "IA-8",
+ "IA-8(4)",
+ "PM-5(1)",
+ "SA-8",
+ "SA-8(22)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.AC-1",
+ "PR.AC-6",
+ "PR.AC-4"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.AA-01",
+ "PR.AA-02",
+ "PR.AA-04",
+ "PR.AA-05"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "2.4.a"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "7.2.5",
+ "7.2.5.1"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "ram_user_console_access_unused"
+ ]
+ },
+ {
+ "Id": "IAM-04",
+ "Description": "Employ the separation of duties principle when implementing information system access.",
+ "Name": "Separation of Duties",
+ "Attributes": [
+ {
+ "Section": "Identity & Access Management",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC1.3",
+ "CC5.1",
+ "CC6.3"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "IAM-05"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "6.8"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "1.2.2",
+ "4.2.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "SA1.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.6.1.2",
+ "27002: 6.1.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.15",
+ "27001: A.5.18",
+ "27001: A.5.3",
+ "27001: A.8.2"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "AC-2",
+ "AC-2(3)",
+ "AC-2(11)",
+ "AC-6",
+ "AC-6(1)-(10)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.AC-4"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.AA-05"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "6.4",
+ "6.4.2"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "6.5.3",
+ "6.5.4",
+ "7.2.1",
+ "7.2.2"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "ram_policy_attached_only_to_group_or_roles"
+ ]
+ },
+ {
+ "Id": "IAM-05",
+ "Description": "Employ the least privilege principle when implementing information system access.",
+ "Name": "Least Privilege",
+ "Attributes": [
+ {
+ "Section": "Identity & Access Management",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC6.3"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "IAM-02",
+ "IAM-06",
+ "IVS-11"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "6.8"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "4.2.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "SA1.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.9.1.1",
+ "27002: 9.1.1",
+ "27001: A.9.1.2",
+ "27002: 9.1.2",
+ "27001: A.9.2.3",
+ "27002: 9.2.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.15",
+ "27001: A.8.2",
+ "27002: 5.15 (Other information 2nd (a))"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "AC-6",
+ "AC-6(4)",
+ "IA-12",
+ "IA-12(2)",
+ "IA-12(3)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.AC-4"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.AA-05"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "7.1",
+ "7.1.1",
+ "7.1.2"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "7.2.1",
+ "7.2.2",
+ "7.2.5",
+ "7.2.6"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "ram_policy_no_administrative_privileges"
+ ]
+ },
+ {
+ "Id": "IAM-07",
+ "Description": "De-provision or respectively modify access of movers / leavers or system identity changes in a timely manner in order to effectively adopt and communicate identity and access management policies.",
+ "Name": "User Access Changes and Revocation",
+ "Attributes": [
+ {
+ "Section": "Identity & Access Management",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC5.3",
+ "CC6.3"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "IAM-11"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "5.3",
+ "6.2"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "4.2.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "SA1.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.15",
+ "27001: A.5.18"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "AC-2",
+ "AC-2(1)",
+ "AC-2(2)",
+ "AC-2(6)",
+ "AC-2(8)",
+ "AC-3",
+ "AC-3(8)",
+ "AC-6",
+ "AC-6(7)",
+ "AU-10",
+ "AU-10(4)",
+ "AU-16",
+ "AU-16(1)",
+ "CM-7",
+ "CM-7(1)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.AC-1",
+ "PR.AC-4",
+ "PR.IP-11"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "GV.RR-04",
+ "GV.SC-10",
+ "PR.AA-01",
+ "PR.AA-05"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "8.1.2",
+ "8.1.3"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "8.2.5",
+ "8.2.6"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "ram_user_console_access_unused"
+ ]
+ },
+ {
+ "Id": "IAM-08",
+ "Description": "Review and revalidate user access for least privilege and separation of duties with a frequency that is commensurate with organizational risk tolerance.",
+ "Name": "User Access Review",
+ "Attributes": [
+ {
+ "Section": "Identity & Access Management",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC6.2",
+ "CC6.3"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "IAM-10"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "5.1"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "4.2.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "SA1.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.9.2.5",
+ "27001: A.9.2.6",
+ "27001: A.9.4.1",
+ "27017: 9.4.1",
+ "27001: A.6.1.2",
+ "27001: A 9.2.5"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.3",
+ "27001: A.5.18",
+ "27001: A.8.3"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "AC-6",
+ "AC-6(4)",
+ "AC-6(8)",
+ "IA-8",
+ "IA-8(4)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.AC-4"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.AA-05"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "12.5.5"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "7.2.5.1",
+ "7.2.5",
+ "7.2.4"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "ram_user_console_access_unused",
+ "ram_rotate_access_key_90_days"
+ ]
+ },
+ {
+ "Id": "IAM-09",
+ "Description": "Define, implement and evaluate processes, procedures and technical measures for the segregation of privileged access roles such that administrative access to data, encryption and key management capabilities and logging capabilities are distinct and separated.",
+ "Name": "Segregation of Privileged Access Roles",
+ "Attributes": [
+ {
+ "Section": "Identity & Access Management",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC5.1",
+ "CC6.1",
+ "CC6.3"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "5.4"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "SA1.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.9.2.3",
+ "27002: 9.2.3",
+ "27017: 9.2.3",
+ "27018: 9.2.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.8.2",
+ "27001: A.8.18",
+ "27002: 8.2 (j)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "AC-6",
+ "AC-3(7)",
+ "AC-6(4)",
+ "AC-6(8)",
+ "IA-5",
+ "IA-5(6)",
+ "IA-8",
+ "IA-8(4)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.AC-1",
+ "PR.AC-4"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.AA-01",
+ "PR.AA-05"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "2.3",
+ "3.5.2",
+ "7.1.2",
+ "7.1.1"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "3.6.1",
+ "3.7.6",
+ "6.5.3",
+ "6.5.4",
+ "7.2.1",
+ "7.2.2",
+ "10.3.1"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "ram_policy_attached_only_to_group_or_roles",
+ "ram_no_root_access_key"
+ ]
+ },
+ {
+ "Id": "IAM-10",
+ "Description": "Define and implement an access process to ensure privileged access roles and rights are granted for a time limited period, and implement procedures to prevent the culmination of segregated privileged access.",
+ "Name": "Management of Privileged Access Roles",
+ "Attributes": [
+ {
+ "Section": "Identity & Access Management",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC6.1",
+ "CC6.2",
+ "CC6.3"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "5.1",
+ "6.5"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "SA1.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.9.2.3",
+ "27002: 9.2.3",
+ "27017: 9.2.3",
+ "27018: 9.2.3",
+ "27001: A.9.4.4",
+ "27002: 9.4.4",
+ "27017: 9.4.4"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.8.2",
+ "27001: A.8.18",
+ "27002: 8.2 (i)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "AC-2",
+ "AC-2(7)",
+ "AC-3",
+ "AC-3(4)",
+ "AC-3(11)",
+ "AC-3(13)",
+ "AC-3(14)",
+ "AC-6",
+ "AC-6(4)",
+ "AC-6(5)",
+ "AC-6(8)",
+ "AC-12",
+ "AC-12(3)",
+ "AC-17",
+ "AC-17(4)",
+ "IA-8",
+ "IA-8(4)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.AC-4"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.AA-05"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "7.1"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "7.2.1",
+ "7.2.2"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "ram_no_root_access_key",
+ "ram_policy_no_administrative_privileges"
+ ]
+ },
+ {
+ "Id": "IAM-12",
+ "Description": "Define, implement and evaluate processes, procedures and technical measures to ensure the logging infrastructure is read-only for all with write access, including privileged access roles, and that the ability to disable it is controlled through a procedure that ensures the segregation of duties and break glass procedures.",
+ "Name": "Safeguard Logs Integrity",
+ "Attributes": [
+ {
+ "Section": "Identity & Access Management",
+ "CCMLite": "No",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "3.3"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "4.2.1",
+ "5.2.4"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "TM1.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.12.4.1",
+ "27002: 12.4.1",
+ "27017: 12.4.1",
+ "27018: 12.4.1",
+ "27001: A.12.4.2",
+ "27002: 12.4.2",
+ "27017: 12.4.2",
+ "27018: 12.4.2",
+ "27001: A.12.4.3",
+ "27002: 12.4.3",
+ "27017: 12.4.3",
+ "27018: 12.4.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.8.15",
+ "27001: A.8.18",
+ "27002: 8.15 Protection of Logs"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "AC-2",
+ "AC-2(11)",
+ "AC-2(12)",
+ "IA-8",
+ "IA-8(4)",
+ "SA-8",
+ "SA-8(22)",
+ "SC-34",
+ "SC-34(1)",
+ "SC-34(2)",
+ "SC-36",
+ "SI-4",
+ "SI-4(5)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.AC-4"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.AA-05"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "10.5"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "10.3.1",
+ "10.3.2",
+ "10.3.3",
+ "10.3.4"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "actiontrail_oss_bucket_not_publicly_accessible"
+ ]
+ },
+ {
+ "Id": "IAM-13",
+ "Description": "Define, implement and evaluate processes, procedures and technical measures that ensure users are identifiable through unique IDs or which can associate individuals to the usage of user IDs.",
+ "Name": "Uniquely Identifiable Users",
+ "Attributes": [
+ {
+ "Section": "Identity & Access Management",
+ "CCMLite": "No",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC6.1"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "4.1.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "SA1.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.9.2.1",
+ "27002: 9.2.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.16"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "AC-3",
+ "AC-3(14)",
+ "AC-24",
+ "AC-24(2)",
+ "AU-10",
+ "AU-10(1)",
+ "IA-2",
+ "IA-2(1)",
+ "IA-2(2)",
+ "IA-2(12)",
+ "IA-4",
+ "IA-4(1)",
+ "SA-8",
+ "SA-8(22)",
+ "SC-23",
+ "SC-23(3)",
+ "SC-40(4)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.AC-1",
+ "PR.AC-6"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.AA-01",
+ "PR.AA-02"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "8.1",
+ "8.2",
+ "8.6"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "8.2.1",
+ "8.2.2",
+ "8.2.4"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "ram_user_mfa_enabled_console_access"
+ ]
+ },
+ {
+ "Id": "IAM-14",
+ "Description": "Define, implement and evaluate processes, procedures and technical measures for authenticating access to systems, application and data assets, including multifactor authentication for at least privileged user and sensitive data access. Adopt digital certificates or alternatives which achieve an equivalent level of security for system identities.",
+ "Name": "Strong Authentication",
+ "Attributes": [
+ {
+ "Section": "Identity & Access Management",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC6.1",
+ "CC6.2"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "IAM-02",
+ "IAM-05"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "6.3",
+ "6.5",
+ "12.5",
+ "12.7"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "4.1.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "SA1.3",
+ "SA1.4",
+ "SA1.8"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.9.1.2",
+ "27002: 9.1.2",
+ "27017: 9.1.2",
+ "27001: A.9.2.4",
+ "27002: 9.2.4",
+ "27017: 9.2.4",
+ "27001: A.9.4.2",
+ "27002: 9.4.2",
+ "27017: 9.4.2",
+ "27018: 9.4.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.15",
+ "27001: A.5.17",
+ "27001: A.8.5",
+ "27001: A.8.24",
+ "27002: 8.5",
+ "27002: 8.24 other information (d)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "AC-6",
+ "AC-6(5)",
+ "AC-7",
+ "AC-7(4)",
+ "AU-10",
+ "AU-10(2)",
+ "IA-2",
+ "IA-2(1)",
+ "IA-2(2)",
+ "IA-2(8)",
+ "IA-2(12)",
+ "IA-3",
+ "IA-3(1)",
+ "IA-5",
+ "IA-5(2)",
+ "IA-5(7)",
+ "IA-5(9)",
+ "IA-5(10)",
+ "IA-5(12)",
+ "IA-5(14)-(16)",
+ "IA-8",
+ "IA-8(1)",
+ "IA-8(6)",
+ "SC-23",
+ "SC-23(3)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.AC-1",
+ "PR.AC-6",
+ "PR.AC-7"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.AA-01",
+ "PR.AA-02",
+ "PR.AA-03"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "8.1.2",
+ "8.1.3",
+ "8.1.6",
+ "8.2",
+ "8.3",
+ "8.3.2",
+ "12.3.2"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "7.2.1",
+ "8.3.1",
+ "8.3.2",
+ "8.4.1",
+ "8.4.2",
+ "8.4.3"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "ram_user_mfa_enabled_console_access"
+ ]
+ },
+ {
+ "Id": "IAM-15",
+ "Description": "Define, implement and evaluate processes, procedures and technical measures for the secure management of passwords.",
+ "Name": "Passwords Management",
+ "Attributes": [
+ {
+ "Section": "Identity & Access Management",
+ "CCMLite": "No",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC6.1",
+ "CC6.2"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "4.1.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "SA1.5"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.9.2.4",
+ "27002: 9.2.4",
+ "27017: 9.2.4",
+ "27018: 9.2.4",
+ "27001: A.9.3.1",
+ "27002: 9.3.1",
+ "27017: 9.3.1",
+ "27018: 9.3.1",
+ "27001: A.9.4.3",
+ "27002: 9.4.3",
+ "27017: 9.4.3",
+ "27018: 9.4.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.17"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "IA-4",
+ "IA-4(8)",
+ "IA-5",
+ "IA-5(1)",
+ "IA-5(8)",
+ "IA-5(18)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.AC-1"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.AA-01"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "8.2",
+ "8.2.1-6"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "2.2.2",
+ "2.3.1",
+ "8.3.5",
+ "8.3.6",
+ "8.3.7",
+ "8.3.8",
+ "8.3.9",
+ "8.3.10",
+ "8.3.10.1",
+ "8.6.2"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "ram_password_policy_minimum_length",
+ "ram_password_policy_password_reuse_prevention",
+ "ram_password_policy_max_password_age"
+ ]
+ },
+ {
+ "Id": "IAM-16",
+ "Description": "Define, implement and evaluate processes, procedures and technical measures to verify access to data and system functions is authorized.",
+ "Name": "Authorization Mechanisms",
+ "Attributes": [
+ {
+ "Section": "Identity & Access Management",
+ "CCMLite": "No",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC6.1",
+ "CC6.2",
+ "CC6.3"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "IAM-02"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "5.1"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "4.2.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "SA1.3",
+ "SA1.4"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.9.2.5",
+ "27002: 9.2.5",
+ "27017: 9.2.5",
+ "27018: 9.2.5"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.18"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "AC-3",
+ "AC-3(5)",
+ "AC-4",
+ "AC-4(17)",
+ "AC-4(21)",
+ "AC-4(22)",
+ "AC-6",
+ "AC-6(8)",
+ "AC-6(9)",
+ "AC-12",
+ "AC-12(1)",
+ "AC-20",
+ "AC-20(1)",
+ "AU-10",
+ "AU-10(1)",
+ "AU-10(2)",
+ "IA-2",
+ "IA-2(1)",
+ "IA-2(2)",
+ "IA-2(12)",
+ "IA-3",
+ "IA-3(1)",
+ "IA-5(1)",
+ "IA-5(2)",
+ "IA-5(5)",
+ "IA-5(8)",
+ "IA-5(10)",
+ "IA-5(12)",
+ "IA-8",
+ "IA-8(1)",
+ "IA-8(2)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.AC-1",
+ "PR.AC-4",
+ "PR.AC-6",
+ "PR.AC-7",
+ "PR.PT-1"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.AA-01",
+ "PR.AA-02",
+ "PR.AA-03",
+ "PR.AA-04",
+ "PR.AA-05",
+ "PR.PS-04"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "5.3",
+ "7.1.4"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "7.2.4",
+ "7.2.3",
+ "7.2.5.1"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "ram_policy_no_administrative_privileges",
+ "cs_kubernetes_rbac_enabled"
+ ]
+ },
+ {
+ "Id": "IPY-03",
+ "Description": "Implement cryptographically secure and standardized network protocols for the management, import and export of data.",
+ "Name": "Secure Interoperability and Portability Management",
+ "Attributes": [
+ {
+ "Section": "Interoperability & Portability",
+ "CCMLite": "No",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC6.7"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "IPY-04"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.1.1",
+ "5.1.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "SY1.1",
+ "SY1.2",
+ "NC1.4"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.18.1",
+ "27001: A.15.1.1",
+ "27002: 15.1.1",
+ "27017: 15.1.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.19",
+ "27001: A.5.23",
+ "27001: A.5.31",
+ "27001: A.5.32",
+ "27001: A.5.33",
+ "27001: A.5.34"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "PT-2",
+ "PT-2(2)",
+ "SA-4",
+ "SC-16",
+ "SC-16(3)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.DS-2"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.DS-02"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "1.2.1",
+ "1.2.5",
+ "1.2.6",
+ "2.2.4",
+ "2.2.5",
+ "2.2.7",
+ "4.2.1"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "oss_bucket_secure_transport_enabled"
+ ]
+ },
+ {
+ "Id": "IVS-02",
+ "Description": "Plan and monitor the availability, quality, and adequate capacity of resources in order to deliver the required system performance as determined by the business.",
+ "Name": "Capacity and Resource Planning",
+ "Attributes": [
+ {
+ "Section": "Infrastructure & Virtualization Security",
+ "CCMLite": "No",
+ "IaaS": "CSP-Owned",
+ "PaaS": "CSP-Owned",
+ "SaaS": "CSP-Owned",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "A1.1"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "IVS-04"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "SY2.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: 5.3",
+ "27001: 6.1",
+ "27001: 9.1",
+ "27001: A.12.1.3",
+ "27002: 12.1.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: 5.3 (b)",
+ "27001: 6.1",
+ "27001: 9.1",
+ "27001: A.8.6",
+ "27001: A.8.14"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "CP-2",
+ "CP-2(2)",
+ "SC-5",
+ "SC-5(2)",
+ "SC-4",
+ "SI-4"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.DS-4",
+ "ID.BE-5"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.IR-04",
+ "GV.OC-04"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": []
+ },
+ {
+ "Id": "IVS-03",
+ "Description": "Monitor, encrypt and restrict communications between environments to only authenticated and authorized connections, as justified by the business. Review these configurations at least annually, and support them by a documented justification of all allowed services, protocols, ports, and compensating controls.",
+ "Name": "Network Security",
+ "Attributes": [
+ {
+ "Section": "Infrastructure & Virtualization Security",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "CSP-Owned",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC6.1",
+ "CC6.7"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "IVS-06"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "3.8",
+ "3.1",
+ "12.2",
+ "13.6",
+ "13.9"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.1.2",
+ "5.2.7"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "NC1.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: 7.5",
+ "27001: 9.1",
+ "27001: A.13.1.1",
+ "27002: 13.1.1",
+ "27001: A.13.1.2",
+ "27002: 13.1.2",
+ "27001: A.13.1.3",
+ "27002: 13.1.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: 7.5",
+ "27001: 9.1",
+ "27001: A.5.15",
+ "27001: A.5.37",
+ "27001: A.8.5",
+ "27001: A.8.9",
+ "27001: A.8.16",
+ "27001: A.8.20",
+ "27001: A.8.21",
+ "27001: A.8.22",
+ "27001: A.8.24",
+ "27002: A.5.15 2nd c)",
+ "27002: 8.20",
+ "27002: 8.21",
+ "27002: 8.22",
+ "27002: 8.24"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "SC-1",
+ "SC-4",
+ "SC-7",
+ "SC-7(4)",
+ "SC-7(5)",
+ "SC-7(8)",
+ "SC-7(9)",
+ "SC-7(11)",
+ "SC-8",
+ "SC-8(1)",
+ "SC-11",
+ "SC-12",
+ "SC-16",
+ "SC-23",
+ "SC-29",
+ "SC-29(1)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.AC-5",
+ "PR.AC-7",
+ "PR.PT-4",
+ "DE.CM-1",
+ "DE.CM-7",
+ "PR.DS-2"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.IR-01",
+ "PR.AA-03",
+ "PR.AA-05",
+ "DE.CM-01",
+ "PR.DS-02",
+ "ID.AM-03"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "1.1.6",
+ "1.2",
+ "1.2.3",
+ "2.2",
+ "4.1.1",
+ "10.2"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "1.2.5",
+ "1.2.6",
+ "1.2.7",
+ "1.4.2",
+ "2.2.4",
+ "2.2.5",
+ "2.2.7",
+ "4.2.1",
+ "10.1.1"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "vpc_flow_logs_enabled",
+ "ecs_securitygroup_restrict_ssh_internet",
+ "ecs_securitygroup_restrict_rdp_internet"
+ ]
+ },
+ {
+ "Id": "IVS-04",
+ "Description": "Harden host and guest OS, hypervisor or infrastructure control plane according to their respective best practices, and supported by technical controls, as part of a security baseline.",
+ "Name": "OS Hardening and Base Controls",
+ "Attributes": [
+ {
+ "Section": "Infrastructure & Virtualization Security",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "CSP-Owned",
+ "SaaS": "CSP-Owned",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC6.1",
+ "CC6.8",
+ "CC7.1"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "IVS-07",
+ "IVS-11"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "4.1",
+ "4.2"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "4.1.3",
+ "5.2.5"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "SY1.1",
+ "SY1.3",
+ "SY1.4"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: 7.5",
+ "27001: 9.1",
+ "27001: A.14.2.2",
+ "27002: 14.2.2",
+ "27001: A.14.2.3",
+ "27001 A.14.2.4",
+ "27018: 12.1.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: 7.5",
+ "27001: 9.1",
+ "27001: A.5.37",
+ "27001: A.8.5",
+ "27001: A.8.9",
+ "27001: A.8.16",
+ "27001: A.8.20",
+ "27001: A.8.22",
+ "27001: A.8.24",
+ "27002: 8.20",
+ "27002: 8.22",
+ "27002: 8.24"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "CM-6",
+ "CM-6(1)",
+ "SC-29",
+ "SC-29(1)",
+ "SC-2",
+ "SC-7",
+ "SC-7(12)",
+ "SC-30",
+ "SC-34",
+ "SC-35",
+ "SC-39",
+ "SC-44"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.IP-1",
+ "PR.PT-3"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.PS-01"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "2.2"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "2.2.1"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "ecs_instance_latest_os_patches_applied",
+ "ecs_instance_endpoint_protection_installed"
+ ]
+ },
+ {
+ "Id": "IVS-06",
+ "Description": "Design, develop, deploy and configure applications and infrastructures such that CSP and CSC (tenant) user access and intra-tenant access is appropriately segmented and segregated, monitored and restricted from other tenants.",
+ "Name": "Segmentation and Segregation",
+ "Attributes": [
+ {
+ "Section": "Infrastructure & Virtualization Security",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "CSP-Owned",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "IVS-09"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "4.2.1",
+ "5.3.4",
+ "5.2.7"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "SC2.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: 9.1",
+ "27001: A.13.1.3",
+ "27002: 13.1.3",
+ "27017: 13.1.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: 9.1",
+ "27001: A.5.15",
+ "27001: A.5.20",
+ "27001: A.8.3",
+ "27001: A.8.9",
+ "27001: A.8.16",
+ "27001: A.8.22",
+ "27002: 5.15 (b)",
+ "27002: 8.3 (b)",
+ "27002: 8.16 (b)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "SC-3",
+ "SC-7",
+ "SC-7(20)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.AC-4",
+ "PR.AC-5"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.AA-05",
+ "PR.IR-01",
+ "PR.PS-01",
+ "PR.PS-06",
+ "DE.CM-09"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "2.6",
+ "8.3.1",
+ "10.8",
+ "11.3",
+ "A3.2.1",
+ "A3.3.1"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "A1.1.1",
+ "A1.1.2",
+ "A1.1.3"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "cs_kubernetes_network_policy_enabled",
+ "cs_kubernetes_private_cluster_enabled",
+ "ecs_instance_no_legacy_network"
+ ]
+ },
+ {
+ "Id": "IVS-07",
+ "Description": "Use secure and encrypted communication channels when migrating servers, services, applications, or data to cloud environments. Such channels must include only up-to-date and approved protocols.",
+ "Name": "Migration to Cloud Environments",
+ "Attributes": [
+ {
+ "Section": "Infrastructure & Virtualization Security",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC6.1",
+ "CC6.7"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "IVS-10"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.1.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "IM1.4",
+ "IM1.4",
+ "NC1.4",
+ "SC2.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.13.1.1",
+ "27002: 13.1.1",
+ "27017: 13.1.1",
+ "27018: 13.1.1",
+ "27001: A.13.1.2",
+ "27002: 13.1.2",
+ "27017: 13.1.2",
+ "27018: 13.1.2",
+ "27001: A.13.1.3",
+ "27002: 13.1.3",
+ "27017: 13.1.3",
+ "27018: 13.1.3",
+ "27001: A.13.2.1",
+ "27002: 13.2.1",
+ "27017: 13.2.1",
+ "27018: 13.2.1",
+ "27001: A.13.2.2",
+ "27002: 13.2.2",
+ "27017: 13.2.2",
+ "27018: 13.2.2",
+ "27001: A.13.2.3",
+ "27002: 13.2.3",
+ "27017: 13.2.3",
+ "27018: 13.2.3",
+ "27001: A.13.2.4",
+ "27002: 13.2.4",
+ "27017: 13.2.4",
+ "27018: 13.2.4"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.14",
+ "27001: A.8.20",
+ "27001: A.8.24",
+ "27002: 8.20 (e)",
+ "27002: 8.24 Guidance (b,f), other information (a)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "AC-17",
+ "AC-20",
+ "SC-7",
+ "SC-7(28)",
+ "SC-8",
+ "SC-8(1)",
+ "SC-12",
+ "SC-23",
+ "SC-29",
+ "SI-7",
+ "SI-7(1)-(3)",
+ "SI-7(5)-(10)",
+ "SI-7(12)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.DS-2",
+ "PR.PT-4"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.DS-02"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "4.2.1"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "rds_instance_ssl_enabled"
+ ]
+ },
+ {
+ "Id": "IVS-09",
+ "Description": "Define, implement and evaluate processes, procedures and defense-in-depth techniques for protection, detection, and timely response to network-based attacks.",
+ "Name": "Network Defense",
+ "Attributes": [
+ {
+ "Section": "Infrastructure & Virtualization Security",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "CSP-Owned",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC6.6",
+ "CC6.8",
+ "CC7.1",
+ "CC7.2",
+ "CC7.5"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "IVS-13"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "13.3",
+ "13.8"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.2.3",
+ "5.2.4",
+ "5.2.5",
+ "5.2.7",
+ "5.3.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "NC1.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: 6.1",
+ "27001: 6.2",
+ "27001: A.14.1.2",
+ "27002: 14.1.2",
+ "27017: 14.1.2",
+ "27001: A.11.1.4",
+ "27002: 11.1.4",
+ "27017: 11.1.4",
+ "27018: 16.1.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: 6.1",
+ "27001: 6.2",
+ "27001: A.5.24",
+ "27001: A.5.26",
+ "27001: A.8.8",
+ "27001: A.8.16",
+ "27001: A.8.20",
+ "27001: A.8.21",
+ "27001: A.8.22",
+ "27001: A.8.26",
+ "27002: 8.8 (i)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "PL-8",
+ "PL-8(1)",
+ "SC-5",
+ "SC-5(1)",
+ "SC-5(3)",
+ "SC-7",
+ "SC-7(13)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "DE.AE-1",
+ "DE.DP-1",
+ "DE.CM-1",
+ "DE.CM-7",
+ "PR.AC-5",
+ "RS.MI-2",
+ "PR.DS-2",
+ "RS.RP-1"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "ID.AM-03",
+ "DE.CM-01",
+ "PR.IR-01",
+ "RS.MA-01",
+ "RS.MI-01",
+ "RS.MI-02"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "6.6",
+ "1.1",
+ "1.2",
+ "1.3",
+ "1.5",
+ "12.10.5"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "1.1.1",
+ "1.3.1",
+ "1.3.2",
+ "1.3.3",
+ "1.4.1",
+ "1.4.2",
+ "1.4.3",
+ "1.4.4",
+ "1.4.5",
+ "1.5.1",
+ "12.10.1"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "securitycenter_advanced_or_enterprise_edition",
+ "sls_cloud_firewall_changes_alert_enabled"
+ ]
+ },
+ {
+ "Id": "LOG-02",
+ "Description": "Define, implement and evaluate processes, procedures and technical measures to ensure the security and retention of audit logs.",
+ "Name": "Audit Logs Protection",
+ "Attributes": [
+ {
+ "Section": "Logging and Monitoring",
+ "CCMLite": "No",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "IVS-01"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "8.1",
+ "8.9",
+ "8.1"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "3.1.3",
+ "5.1.2",
+ "5.2.4"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "TM1.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.18.1.3",
+ "27002: 18.1.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.28",
+ "27001: A.5.33",
+ "27001: A.8.15"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "AU-4",
+ "AU-11"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.AC-4",
+ "PR.IP-4",
+ "PR.IP-6",
+ "PR.PT-1",
+ "PR.DS-1"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.AA-05",
+ "PR.DS-01",
+ "PR.DS-02",
+ "ID.AM-08",
+ "PR.DS-11",
+ "PR.PS-04"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "10.5",
+ "10.7"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "10.3.1",
+ "10.3.2",
+ "10.3.3",
+ "10.3.4",
+ "10.5.1"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "actiontrail_oss_bucket_not_publicly_accessible",
+ "sls_logstore_retention_period"
+ ]
+ },
+ {
+ "Id": "LOG-03",
+ "Description": "Identify and monitor security-related events within applications and the underlying infrastructure. Define and implement a system to generate alerts to responsible stakeholders based on such events and corresponding metrics.",
+ "Name": "Security Monitoring and Alerting",
+ "Attributes": [
+ {
+ "Section": "Logging and Monitoring",
+ "CCMLite": "No",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC6.8",
+ "CC7.3"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "SEF-03",
+ "SEF-05"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "8.5"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.2.4",
+ "5.2.7",
+ "1.6.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "TM1.2",
+ "TM1.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.12.4.1",
+ "27002: 12.4.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.28",
+ "27001: A.8.15"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "AU-5",
+ "AU-5(2)",
+ "AU-13"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "DE.AE-1",
+ "DE.AE-2",
+ "DE.AE-3",
+ "DE.AE-5",
+ "DE.CM-1",
+ "DE.CM-2",
+ "DE.CM-3",
+ "DE.CM-4",
+ "DE.CM-5",
+ "DE.CM-6",
+ "DE.CM-7",
+ "DE.DP-1",
+ "DE.DP-4",
+ "DE.AE-4"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.PS-04",
+ "DE.AE-02",
+ "DE.AE-03",
+ "DE.AE-04",
+ "DE.AE-06",
+ "DE.AE-07",
+ "DE.AE-08",
+ "DE.CM-01",
+ "DE.CM-02",
+ "DE.CM-03",
+ "DE.CM-06",
+ "DE.CM-09"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "10.2"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "10.2.1",
+ "10.2.2",
+ "10.4.1.1",
+ "10.4.2.1",
+ "10.4.3"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "securitycenter_advanced_or_enterprise_edition",
+ "securitycenter_notification_enabled_high_risk",
+ "sls_unauthorized_api_calls_alert_enabled",
+ "sls_root_account_usage_alert_enabled",
+ "sls_management_console_signin_without_mfa_alert_enabled"
+ ]
+ },
+ {
+ "Id": "LOG-04",
+ "Description": "Restrict audit logs access to authorized personnel and maintain records that provide unique access accountability.",
+ "Name": "Audit Logs Access and Accountability",
+ "Attributes": [
+ {
+ "Section": "Logging and Monitoring",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "IVS-01"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "3.14"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "3.1.1",
+ "4.1.2",
+ "4.1.3",
+ "4.2.1",
+ "5.2.4"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "TM1.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.12.4.2",
+ "27001: A.12.4.1",
+ "27002: 12.4.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.33",
+ "27001: A.8.15"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "AU-9",
+ "AU-9(4)",
+ "AU-9(6)",
+ "AU-10"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.AC-1",
+ "PR.AC-4"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.AA-05",
+ "PR.PS-04"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "10.1",
+ "10.2.1",
+ "10.2.3",
+ "10.5.1",
+ "10.5.2"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "10.2.1.3",
+ "10.3.1"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "actiontrail_oss_bucket_not_publicly_accessible"
+ ]
+ },
+ {
+ "Id": "LOG-05",
+ "Description": "Monitor security audit logs to detect activity outside of typical or expected patterns. Establish and follow a defined process to review and take appropriate and timely actions on detected anomalies.",
+ "Name": "Audit Logs Monitoring and Response",
+ "Attributes": [
+ {
+ "Section": "Logging and Monitoring",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC7.2"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "8.8",
+ "8.11"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "1.6.1",
+ "1.6.2",
+ "5.2.4"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "TM1.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.12.4.3",
+ "27002: 12.4.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.8.15",
+ "27001: A.8.16"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "AU-6",
+ "AU-6(1)",
+ "AU-6(5)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "DE.AE-3",
+ "PR.PT-1",
+ "RS.AN-1",
+ "RS.CO-1.",
+ "DE.AE-1",
+ "DE.AE-5",
+ "DE.DP-4"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "ID.AM-03",
+ "PR.PS-04",
+ "DE.AE-02",
+ "DE.AE-03",
+ "DE.AE-06",
+ "DE.AE-07",
+ "DE.AE-08",
+ "DE.CM-01",
+ "DE.CM-02",
+ "DE.CM-03",
+ "DE.CM-06",
+ "DE.CM-09"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "10.6",
+ "10.6.1"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "10.4.1.1",
+ "10.4.2.1"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "sls_unauthorized_api_calls_alert_enabled",
+ "sls_root_account_usage_alert_enabled",
+ "sls_management_console_signin_without_mfa_alert_enabled",
+ "sls_ram_role_changes_alert_enabled",
+ "sls_security_group_changes_alert_enabled",
+ "sls_vpc_changes_alert_enabled",
+ "sls_vpc_network_route_changes_alert_enabled",
+ "sls_management_console_authentication_failures_alert_enabled",
+ "sls_customer_created_cmk_changes_alert_enabled",
+ "sls_oss_bucket_policy_changes_alert_enabled",
+ "sls_oss_permission_changes_alert_enabled",
+ "sls_cloud_firewall_changes_alert_enabled",
+ "sls_rds_instance_configuration_changes_alert_enabled"
+ ]
+ },
+ {
+ "Id": "LOG-07",
+ "Description": "Establish, document and implement which information meta/data system events should be logged. Review and update the scope at least annually or whenever there is a change in the threat environment.",
+ "Name": "Logging Scope",
+ "Attributes": [
+ {
+ "Section": "Logging and Monitoring",
+ "CCMLite": "No",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC7.2"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "8.1"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.2.4"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "TM1.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: 7.5.3",
+ "27001: A.12.4.1",
+ "27002: 12.4.1",
+ "27017: 12.4.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: 7.5.3",
+ "27001: A.8.15"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "AU-1",
+ "AU-14",
+ "AU-16"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "ID.SC-3",
+ "ID.SC-4",
+ "PR.PT-1",
+ "ID.GV-1"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.PS-04"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "10.3"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "10.2.1",
+ "10.2.2"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "actiontrail_multi_region_enabled",
+ "vpc_flow_logs_enabled"
+ ]
+ },
+ {
+ "Id": "LOG-08",
+ "Description": "Generate audit records containing relevant security information.",
+ "Name": "Log Records",
+ "Attributes": [
+ {
+ "Section": "Logging and Monitoring",
+ "CCMLite": "No",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC7.2"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "8.2"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.2.4"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "TM1.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.12.4.1",
+ "27002: 12.4.1",
+ "27017: 12.4.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.8.15"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "AU-3",
+ "AU-3(1)",
+ "AU-3(3)",
+ "AU-6",
+ "AU-6(8)",
+ "AU-12",
+ "AU-12(1)",
+ "AU-12(2)",
+ "AU-12(3)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.PT-1",
+ "DE.AE-3",
+ "DE.CM-1",
+ "DE.CM-2",
+ "DE.CM-3",
+ "DE.CM-6",
+ "DE.CM-7"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.PS-04",
+ "DE.CM-01",
+ "DE.CM-02",
+ "DE.CM-03",
+ "DE.CM-06",
+ "DE.CM-09"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "10.3"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "10.2.2"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "actiontrail_multi_region_enabled",
+ "vpc_flow_logs_enabled",
+ "oss_bucket_logging_enabled",
+ "rds_instance_sql_audit_enabled",
+ "cs_kubernetes_log_service_enabled",
+ "rds_instance_postgresql_log_connections_enabled",
+ "rds_instance_postgresql_log_disconnections_enabled",
+ "rds_instance_postgresql_log_duration_enabled"
+ ]
+ },
+ {
+ "Id": "LOG-09",
+ "Description": "The information system protects audit records from unauthorized access, modification, and deletion.",
+ "Name": "Log Protection",
+ "Attributes": [
+ {
+ "Section": "Logging and Monitoring",
+ "CCMLite": "No",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "GRM-04",
+ "IVS-01"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.2.4",
+ "4.2.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "TM1.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.12.4.2",
+ "27002: 12.4.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.8.15"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "AU-9",
+ "AU-9(2)",
+ "AU-9(3)",
+ "AU-9(4)",
+ "AU-12(3)",
+ "AU-12(3)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.AC-4",
+ "PR.IP-4",
+ "PR.IP-6",
+ "PR.PT-1",
+ "PR.DS-1",
+ "PR.DS-6"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.AA-05",
+ "PR.DS-01",
+ "PR.DS-02",
+ "PR.DS-11"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "10.5",
+ "10.5.1",
+ "10.5.2"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "10.3.1",
+ "10.3.2",
+ "10.3.3",
+ "10.3.4"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "actiontrail_oss_bucket_not_publicly_accessible"
+ ]
+ },
+ {
+ "Id": "LOG-10",
+ "Description": "Establish and maintain a monitoring and internal reporting capability over the operations of cryptographic, encryption and key management policies, processes, procedures, and controls.",
+ "Name": "Encryption Monitoring and Reporting",
+ "Attributes": [
+ {
+ "Section": "Logging and Monitoring",
+ "CCMLite": "No",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC6.1",
+ "CC7.2"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "EKM-02",
+ "EKM-03"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "4.2.1",
+ "5.1.1",
+ "5.1.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "TS2.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.10.1",
+ "27002: 10.1",
+ "27001: A.10.1.2",
+ "27017: 10.1.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.8.24"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "AU-1",
+ "AU-9",
+ "AU-9(3)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "ID.GV-1",
+ "PR.PT-1"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.PS-04",
+ "DE.CM-09"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "10.1.1",
+ "10.2.1",
+ "10.4.1"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "sls_customer_created_cmk_changes_alert_enabled"
+ ]
+ },
+ {
+ "Id": "LOG-11",
+ "Description": "Log and monitor key lifecycle management events to enable auditing and reporting on usage of cryptographic keys.",
+ "Name": "Transaction/Activity Logging",
+ "Attributes": [
+ {
+ "Section": "Logging and Monitoring",
+ "CCMLite": "No",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC6.1",
+ "CC7.2"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "EKM-02"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.1.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "TS2.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.10.1.2",
+ "27017: 10.1.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.8.24"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "AU-9",
+ "AU-9(3)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.PT-1",
+ "DE.AE-3"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.PS-04",
+ "DE.CM-09"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "actiontrail_multi_region_enabled"
+ ]
+ },
+ {
+ "Id": "LOG-13",
+ "Description": "Define, implement and evaluate processes, procedures and technical measures for the reporting of anomalies and failures of the monitoring system and provide immediate notification to the accountable party.",
+ "Name": "Failures and Anomalies Reporting",
+ "Attributes": [
+ {
+ "Section": "Logging and Monitoring",
+ "CCMLite": "No",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC2.3",
+ "CC7.3"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "SEF-03"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "1.6.1",
+ "5.2.4"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "TM1.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.16.1.1",
+ "27002: 16.1.1",
+ "27001: A.16.1.2",
+ "27017: 16.1.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.24",
+ "27001: A.6.8",
+ "27002: 6.8 (g)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "AU-5",
+ "AU-5(2)",
+ "AU-6",
+ "AU-6(3)",
+ "AU-6(4)",
+ "AU-6(5)",
+ "AU-16"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "DE.DP-3",
+ "DE.DP-4"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.PS-04",
+ "DE.AE-06"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "10.6"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "10.4.3",
+ "10.7.1",
+ "10.7.2",
+ "10.7.3"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "securitycenter_advanced_or_enterprise_edition",
+ "securitycenter_notification_enabled_high_risk"
+ ]
+ },
+ {
+ "Id": "SEF-03",
+ "Description": "'Establish, document, approve, communicate, apply, evaluate and maintain a security incident response plan, which includes but is not limited to: relevant internal departments, impacted CSCs, and other business critical relationships (such as supply-chain) that may be impacted.'",
+ "Name": "Incident Response Plans",
+ "Attributes": [
+ {
+ "Section": "Security Incident Management, E-Discovery, & Cloud Forensics",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC7.2",
+ "CC7.3",
+ "CC7.4"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "BCR-02"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "17.2",
+ "17.4"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "1.6.2",
+ "1.6.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "TM2.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: 5.2",
+ "27001: 7.3",
+ "27001: 7.4",
+ "27001: 7.5",
+ "27001: A.16.1.5",
+ "27002: 16.1.5",
+ "27017: 16.1.5",
+ "27017: CLD.12.1.5",
+ "27018: 16.1.5"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: 5.2",
+ "27001: 7.3",
+ "27001: 7.4",
+ "27001: 7.5",
+ "27001: A.5.26",
+ "27002: 5.26 (e,f)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "IR-1",
+ "IR-2",
+ "IR-2(1)-(3)",
+ "IR-3",
+ "IR-3(1)-(3)",
+ "IR-4",
+ "IR-4(1)-(15)",
+ "IR-5",
+ "IR-5(1)",
+ "IR-6",
+ "IR-6(1)-(3)",
+ "IR-7",
+ "IR-7(1)",
+ "IR-7(2)",
+ "IR-8",
+ "IR-8(1)",
+ "IR-9",
+ "IR-9(1)-(4)",
+ "PM-12"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "RS.CO-1",
+ "RS.CO-4",
+ "ID.AM-6",
+ "ID.GV-2",
+ "ID.SC-5",
+ "PR.IP-9",
+ "PR.IP10"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.AT-01",
+ "PR.AT-02",
+ "RS.MA-01",
+ "GV.SC-08",
+ "ID.IM-02",
+ "ID.IM-04",
+ "RC.RP-01"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "12.1",
+ "12.10.1"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "12.10.1",
+ "12.10.5"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": []
+ },
+ {
+ "Id": "SEF-06",
+ "Description": "Define, implement and evaluate processes, procedures and technical measures supporting business processes to triage security-related events.",
+ "Name": "Event Triage Processes",
+ "Attributes": [
+ {
+ "Section": "Security Incident Management, E-Discovery, & Cloud Forensics",
+ "CCMLite": "No",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC7.3"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "SEF-02"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "1.6.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "TM1.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.16.1.4",
+ "27002: 16.1.4",
+ "27017: 16.1.4",
+ "27018: 16.1.4",
+ "27001: A.16.1.5",
+ "27002: 16.1.5",
+ "27017: 16.1.5",
+ "27018: 16.1.5"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.25"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "CA-7",
+ "CA-7(3)",
+ "CA-7(4)",
+ "CA-7(5)",
+ "CA-7(6)",
+ "IR-4",
+ "IR-4(1)",
+ "IR-4(3)",
+ "IR-4(4)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "DE.AE-1",
+ "DE.AE-2",
+ "DE.AE-4",
+ "RS.RP-1",
+ "RS.AN-2"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "RS.MA-02",
+ "RS.MA-03",
+ "RS.AN-03",
+ "DE.AE-02",
+ "DE.AE-04",
+ "DE.AE-06",
+ "DE.AE-07",
+ "DE.AE-08",
+ "RS.MI-02",
+ "RC.RP-02"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "12.5.2"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "12.10.1"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "securitycenter_advanced_or_enterprise_edition"
+ ]
+ },
+ {
+ "Id": "SEF-08",
+ "Description": "Maintain points of contact for applicable regulation authorities, national and local law enforcement, and other legal jurisdictional authorities.",
+ "Name": "Points of Contact Maintenance",
+ "Attributes": [
+ {
+ "Section": "Security Incident Management, E-Discovery, & Cloud Forensics",
+ "CCMLite": "No",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC2.3"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "SEF-01"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "17.2"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "1.6.2",
+ "1.6.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "SM2.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: 4.2",
+ "27001: A.6.1.3",
+ "27002: 6.1.3",
+ "27017: 6.1.3",
+ "27018: 6.1.3",
+ "27001: A.16.1.1",
+ "27002: 16.1.1",
+ "27001: A.18.1.1",
+ "27002: 18.1.1",
+ "27017: 18.1.1",
+ "27018: 18.1.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.5",
+ "27001: A.5.24",
+ "27002: 5.24 Incident management procedure (d)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "IR-4",
+ "IR-4(8)",
+ "IR-6",
+ "IR-6(3)",
+ "IR-7",
+ "IR-7(2)",
+ "PM-21",
+ "PM-23",
+ "PM-26"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "ID.GV-2",
+ "RS.CO-3",
+ "RS.CO-4"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "GV.RR-02",
+ "RS.CO-02",
+ "RS.CO-03"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "12.10.1"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": []
+ },
+ {
+ "Id": "TVM-02",
+ "Description": "Establish, document, approve, communicate, apply, evaluate and maintain policies and procedures to protect against malware on managed assets. Review and update the policies and procedures at least annually.",
+ "Name": "Malware Protection Policy and Procedures",
+ "Attributes": [
+ {
+ "Section": "Threat & Vulnerability Management",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC5.3",
+ "CC6.8"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "TVM-01",
+ "GRM-06",
+ "GRM-09"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "9.7",
+ "10.1"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "1.1.1",
+ "1.5.1",
+ "5.2.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "TS1.2",
+ "TS1.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: 5.1",
+ "27001: 5.2",
+ "27001: 7.3",
+ "27001: 7.4",
+ "27001: 7.5",
+ "27001: 9.1",
+ "27001: 9.3",
+ "27001: A.5",
+ "27002: 5",
+ "27001: A.12.2.1",
+ "27001: A.6.2.1",
+ "27002: 6.2.1 (h)",
+ "27001: A.6.2.2",
+ "27002: 6.2.2 (j)",
+ "27001: A.7.2.2",
+ "27002: 7.2.2 (d)",
+ "27001: A.10.1.1",
+ "27002: 10.1.1 (g)",
+ "27001: A.13.2.1",
+ "27002: 13.2.1 (b)",
+ "27001: A.15.1.2",
+ "27017: 15.1.2",
+ "27001: A.12.2.1",
+ "27002: 12.2.1 (a),(d)",
+ "27017: CLD.9.5.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: 5.1",
+ "27001: 5.2",
+ "27001: 7.3",
+ "27001: 7.4",
+ "27001: 7.5",
+ "27001: 9.1",
+ "27001: 9.3",
+ "27001: A.5.1",
+ "27001: A.5.4",
+ "27001: A.5.7",
+ "27001: A.5.37",
+ "27001: A.8.7",
+ "27002: 5.7 (b)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "RA-3",
+ "RA-3(3)",
+ "RA-5",
+ "RA-5(3)",
+ "RA-5(5)",
+ "SI-3",
+ "SI-3(4)",
+ "SI-3(10)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "ID.GV-1",
+ "DE.CM-4",
+ "DE.CM-5"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "GV.PO-01",
+ "GV.PO-02",
+ "ID.IM-03",
+ "DE.CM-01",
+ "DE.CM-09"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "5.4",
+ "12.1",
+ "12.1.1",
+ "12.3.1",
+ "12.5.1",
+ "12.11"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "12.1.1",
+ "12.1.2",
+ "5.1.1",
+ "5.3.2.1"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "ecs_instance_endpoint_protection_installed"
+ ]
+ },
+ {
+ "Id": "TVM-03",
+ "Description": "Define, implement and evaluate processes, procedures and technical measures to enable both scheduled and emergency responses to vulnerability identifications, based on the identified risk.",
+ "Name": "Vulnerability Remediation Schedule",
+ "Attributes": [
+ {
+ "Section": "Threat & Vulnerability Management",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC5.3",
+ "CC7.1",
+ "CC7.4"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "TVM-02"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "7.2",
+ "7.7",
+ "17.9"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.2.5"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "TM1.1",
+ "TM2.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: 6.1.3",
+ "27001: A.12.2.1",
+ "27001: A.12.6.1",
+ "27002: 12.6.1(c)(d)(j)",
+ "27018: 12.6.1(k)(i)"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: 6.1.3",
+ "27001: A.8.7",
+ "27001: A.8.8",
+ "27001: A.8.32",
+ "27002: 8.7",
+ "27002: 8.8",
+ "27002: 8.32"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "PM-31",
+ "RA-3",
+ "RA-3(1)",
+ "RA-5",
+ "RA-5(2)-(4)",
+ "RA-5(6)",
+ "SI-3",
+ "SI-3(10)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "RS.AN-5",
+ "PR.IP-12"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "ID.RA-01",
+ "ID.RA-06",
+ "ID.RA-08",
+ "PR.PS-02",
+ "PR.PS-03"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "6.1",
+ "6.1.a",
+ "6.1.b"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "6.1.1",
+ "6.3.1",
+ "6.3.2",
+ "6.3.3",
+ "12.10.1"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "ecs_instance_latest_os_patches_applied"
+ ]
+ },
+ {
+ "Id": "TVM-04",
+ "Description": "Define, implement and evaluate processes, procedures and technical measures to update detection tools, threat signatures, and indicators of compromise on a weekly, or more frequent basis.",
+ "Name": "Detection Updates",
+ "Attributes": [
+ {
+ "Section": "Threat & Vulnerability Management",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC7.2"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "No mapping"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "10.2"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.2.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "TS1.3",
+ "TS1.4",
+ "TM1.3",
+ "TM1.4",
+ "IM1.5"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: 6.1.3",
+ "27001: A.5.1.1",
+ "27002: 5.1.1 (h)",
+ "27001: A.12.6.1",
+ "27002: 12.6.1 (b),(c)"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: 6.1.3",
+ "27001: A.5.1",
+ "27001: A.8.8",
+ "27001: A.8.15",
+ "27001: A.8.16",
+ "27002: 5.1",
+ "27002: 5.37",
+ "27002: 8.8",
+ "27002: 8.15 (d)",
+ "27002: 8.16 (d,e)",
+ "27002: 8.31 2nd (a)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "CM-7",
+ "CM-7(4)",
+ "RA-3",
+ "RA-3(3)",
+ "RA-5(2)",
+ "SA-10",
+ "SA-10(5)",
+ "SA-11",
+ "SA-11(2)",
+ "SI-2",
+ "SI-2(4)",
+ "SI-3",
+ "SI-3(4)",
+ "SI-4",
+ "SI-4(9)",
+ "SI-4(24)",
+ "SI-8",
+ "SI-8(2)",
+ "SI-8(3)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "DE.DP-5",
+ "PR.IP-12"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.PS-02",
+ "ID.RA-02"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "5.2",
+ "5.2a",
+ "5.2b",
+ "5.2c"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "5.3.1"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "securitycenter_advanced_or_enterprise_edition",
+ "securitycenter_vulnerability_scan_enabled"
+ ]
+ },
+ {
+ "Id": "TVM-05",
+ "Description": "Define, implement and evaluate processes, procedures and technical measures to identify updates for applications which use third party or open source libraries according to the organization's vulnerability management policy.",
+ "Name": "External Library Vulnerabilities",
+ "Attributes": [
+ {
+ "Section": "Threat & Vulnerability Management",
+ "CCMLite": "No",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "CSP-Owned",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC3.2"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "No mapping"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "2.6"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "TM1.1",
+ "SD2.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: 6.1.3",
+ "27001: A.12.6.2",
+ "27002: 12.6.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: 6.1.3",
+ "27001: A 5.6",
+ "27001: A.8.19",
+ "27001: A.8.8",
+ "27001: A.8.28",
+ "27001: A.8.31",
+ "27002: 5.6 (c)",
+ "27001: 8.19",
+ "27001: 8.8",
+ "27001: 8.28",
+ "27001: 8.31"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "RA-5",
+ "RA-5(3)",
+ "SA-11",
+ "SA-11(2)",
+ "SA-11(5)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "DE.DP-5",
+ "PR.IP-12"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "ID.RA-01",
+ "ID.RA-03",
+ "PR.PS-02"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "6.1",
+ "6.2",
+ "6.3.2"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "6.3.1",
+ "6.3.2",
+ "6.3.3"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "securitycenter_vulnerability_scan_enabled"
+ ]
+ },
+ {
+ "Id": "TVM-07",
+ "Description": "Define, implement and evaluate processes, procedures and technical measures for the detection of vulnerabilities on organizationally managed assets at least monthly.",
+ "Name": "Vulnerability Identification",
+ "Attributes": [
+ {
+ "Section": "Threat & Vulnerability Management",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC7.1"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "TVM-02"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "7.1",
+ "7.5",
+ "7.6"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.2.5",
+ "5.2.6"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "TM1.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.12.6",
+ "27001: A.12.6.1",
+ "27002: 12.6.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.8.8",
+ "27002: 8.8"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "RA-5",
+ "RA-5(4)",
+ "RA-5(5)",
+ "SA-11",
+ "SA-11(5)",
+ "SA-15(5)",
+ "SC-7",
+ "SC-7(10)",
+ "SI-3(8)",
+ "SI-3(10)",
+ "SI-7",
+ "SI-7(9)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "ID.RA-1",
+ "DE.CM-8",
+ "PR.IP-12"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "ID.RA-01"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "6.1",
+ "11.2",
+ "11.2.1"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "6.3.1",
+ "6.3.2",
+ "6.3.3",
+ "11.3.2",
+ "11.3.2.1"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "securitycenter_vulnerability_scan_enabled",
+ "securitycenter_advanced_or_enterprise_edition"
+ ]
+ },
+ {
+ "Id": "UEM-08",
+ "Description": "Protect information from unauthorized disclosure on managed endpoint devices with storage encryption.",
+ "Name": "Storage Encryption",
+ "Attributes": [
+ {
+ "Section": "Universal Endpoint Management",
+ "CCMLite": "No",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC6.1",
+ "CC6.7"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "MOS-11"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "3.6"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.1.2",
+ "3.1.4"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "PA1.2",
+ "PA1.3",
+ "PA1.5",
+ "PA2.2",
+ "PM1.4"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.11.2.7",
+ "27002: 11.2.7",
+ "27001: A.18.1.1",
+ "27017: 18.1.1",
+ "27001: A.12.3.1",
+ "27017: 12.3.1",
+ "27018: A.11.4",
+ "27018: A.11.5"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.8.1",
+ "27002: 8.1 (h)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "AC-19(5)",
+ "SC-28",
+ "SC-28(1)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.DS-1"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.DS-01"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "3.4",
+ "3.6"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "3.5.1",
+ "3.6"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "ecs_attached_disk_encrypted",
+ "ecs_unattached_disk_encrypted"
+ ]
+ },
+ {
+ "Id": "UEM-11",
+ "Description": "Configure managed endpoints with Data Loss Prevention (DLP) technologies and rules in accordance with a risk assessment.",
+ "Name": "Data Loss Prevention",
+ "Attributes": [
+ {
+ "Section": "Universal Endpoint Management",
+ "CCMLite": "No",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC6.7"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "3.13"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.2.7"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "IM1.5",
+ "PA2.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.12.3",
+ "27002: 12.3",
+ "27001: A.8.3.1",
+ "27002: 8.3.1",
+ "27001: A.12.2",
+ "27002: 12.2",
+ "27001: A.18.1.3",
+ "27002: 18.1.3",
+ "27001: A.6.1.1",
+ "27017: 6.1.1",
+ "27018: 12.3.1",
+ "27018: 10.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.12",
+ "27001: A.8.3"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "SC-7",
+ "SC-7(10)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.DS-5"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.DS-02",
+ "PR.DS-10",
+ "PR.PS-01",
+ "ID.AM-08",
+ "DE.CM-09"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "A3.2.6"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "A3.2.6"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": []
+ }
+ ]
+}
diff --git a/prowler/compliance/aws/csa_ccm_4.0_aws.json b/prowler/compliance/aws/csa_ccm_4.0_aws.json
new file mode 100644
index 0000000000..6d0a019c2b
--- /dev/null
+++ b/prowler/compliance/aws/csa_ccm_4.0_aws.json
@@ -0,0 +1,7604 @@
+{
+ "Framework": "CSA-CCM",
+ "Name": "CSA Cloud Controls Matrix (CCM) v4.0.13",
+ "Version": "4.0",
+ "Provider": "AWS",
+ "Description": "The Cloud Security Alliance (CSA) Cloud Controls Matrix (CCM) is a cybersecurity control framework for cloud computing, composed of 197 control objectives structured in 17 domains covering all key aspects of cloud technology. The CCM can be used as a tool for the systematic assessment of a cloud implementation, and provides guidance on which security controls should be implemented by which actor within the cloud supply chain.",
+ "Requirements": [
+ {
+ "Id": "A&A-02",
+ "Description": "Conduct independent audit and assurance assessments according to relevant standards at least annually.",
+ "Name": "Independent Assessments",
+ "Attributes": [
+ {
+ "Section": "Audit & Assurance",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC4.1"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "AAC-02"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "1.5.2",
+ "5.2.6"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "AS1.1",
+ "AS2.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.18.2.1",
+ "27002: 18.2.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.35",
+ "27001: A.5.36"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "CA-2",
+ "CA-2(1)",
+ "CA-2(2)",
+ "CA-7",
+ "CA-7(1)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "ID.IM-01"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "securityhub_enabled"
+ ]
+ },
+ {
+ "Id": "A&A-04",
+ "Description": "Verify compliance with all relevant standards, regulations, legal/contractual, and statutory requirements applicable to the audit.",
+ "Name": "Requirements Compliance",
+ "Attributes": [
+ {
+ "Section": "Audit & Assurance",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC3.1"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "GRM-01",
+ "GRM-03"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "7.1.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "AS1.1",
+ "AS2.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: 9.3.2",
+ "27001: A.18.2.2",
+ "27002: 18.2.2",
+ "27001: A.18.2.3",
+ "27002: 18.2.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: 9.3.2",
+ "27001: A.5.31",
+ "27001: A.5.32",
+ "27001: A.5.33",
+ "27001: A.5.34",
+ "27001: A.5.36"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "CA-1"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "ID.GV-3",
+ "DE.DP-2"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "ID.IM-01"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "securityhub_enabled",
+ "config_recorder_all_regions_enabled"
+ ]
+ },
+ {
+ "Id": "AIS-04",
+ "Description": "Define and implement a SDLC process for application design, development, deployment, and operation in accordance with security requirements defined by the organization.",
+ "Name": "Secure Application Design and Development",
+ "Attributes": [
+ {
+ "Section": "Application & Interface Security",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "CSP-Owned",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC6.8",
+ "CC8.1"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "AIS-01",
+ "AIS-03"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "16.1"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "1.3.4",
+ "5.3.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "SD1.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.14.1.1",
+ "27002: 14.1.1",
+ "27017: 14.1.1",
+ "27001: A.14.1.2",
+ "27002: 14.1.2",
+ "27017: 14.1.2",
+ "27001: A.14.2.1",
+ "27002: 14.2.1",
+ "27017: 14.2.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.8",
+ "27001: A.8.25",
+ "27001: A.8.26",
+ "27001: A.8.28"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "PL-2",
+ "PL-8",
+ "PL-8(1)",
+ "SA-3",
+ "SA-3(1)",
+ "SA-4",
+ "SA-4(2)",
+ "SA-4(3)",
+ "SA-4(8)",
+ "SA-4(9)",
+ "SA-5",
+ "SA-8",
+ "SA-8(1)-(7)",
+ "SA-8(9)-(13)",
+ "SA-8(15)-(20)",
+ "SA-8(22)",
+ "SA-8(24)-(28)",
+ "SA-8(30)-(33)",
+ "SA-17",
+ "SA-17(1)-(9)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.DS-6",
+ "PR.DS-7",
+ "PR.IP-2"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "ID.AM-08",
+ "PR.IR-01",
+ "PR.PS-01",
+ "PR.PS-02",
+ "PR.PS-06"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "6.3"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "6.2.1",
+ "6.2.3",
+ "6.5.2"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "codebuild_project_source_repo_url_no_sensitive_credentials",
+ "codebuild_project_no_secrets_in_variables"
+ ]
+ },
+ {
+ "Id": "AIS-05",
+ "Description": "Implement a testing strategy, including criteria for acceptance of new information systems, upgrades and new versions, which provides application security assurance and maintains compliance while enabling organizational speed of delivery goals. Automate when applicable and possible.",
+ "Name": "Automated Application Security Testing",
+ "Attributes": [
+ {
+ "Section": "Application & Interface Security",
+ "CCMLite": "No",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC6.8",
+ "CC8.1"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "AIS-01",
+ "AIS-03"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "16.12",
+ "16.13"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "SD2.3",
+ "SD2.5"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.14.2.8",
+ "27001: A.14.2.9",
+ "27001: A.12.1.2",
+ "27002: 12.1.2",
+ "27001: A.14.1.1",
+ "27002: 14.1.1",
+ "27001: A.14.2.2",
+ "27002: 14.2.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.8.25",
+ "27001: A.8.29",
+ "27001: A.8.32",
+ "27002: 8.25 (e)",
+ "27002: 8.32 (d)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "SA-11",
+ "SA-11(1)-(9)",
+ "SI-6",
+ "SI-6(2)",
+ "SI-6(3)",
+ "SI-10",
+ "SI-10(1)-(6)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.IP-2",
+ "PR.PT-3",
+ "PR.IP-12",
+ "DE.CM-8"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "ID.AM-08",
+ "ID.RA-01",
+ "PR.PS-01",
+ "PR.PS-02"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "A.3.2.2",
+ "A.3.2.2.1",
+ "6.6"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "6.2.4",
+ "6.4.1",
+ "6.4.2",
+ "6.5.1"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "inspector2_is_enabled",
+ "ecr_repositories_scan_vulnerabilities_in_latest_image",
+ "ecr_registry_scan_images_on_push_enabled"
+ ]
+ },
+ {
+ "Id": "AIS-07",
+ "Description": "Define and implement a process to remediate application security vulnerabilities, automating remediation when possible.",
+ "Name": "Application Vulnerability Remediation",
+ "Attributes": [
+ {
+ "Section": "Application & Interface Security",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC7.1",
+ "CC7.4",
+ "CC8.1"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "TVM-02"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "16.2",
+ "16.6"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "TM1.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.16.1.5",
+ "27002: 16.1.5",
+ "27017: 16.1.5",
+ "27001: A.12.6.1",
+ "27002: 12.6.1",
+ "27017: 12.6.1",
+ "27018: 12.6.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.26",
+ "27001: A.8.8",
+ "27002: 5.26 (j)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "SI-2",
+ "SI-2(2)-(6)",
+ "SA-11",
+ "SA-11(2)",
+ "SA-15",
+ "SA-15(1)-(3)",
+ "SA-15(5)-(8)",
+ "SA-15(10)-(12)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.IP-2",
+ "PR.IP-12",
+ "DE.CM-8",
+ "RS.AN-5",
+ "RS.MI-3",
+ "PR.DS-6"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "ID.AM-08",
+ "ID.RA-01",
+ "ID.RA-06",
+ "ID.RA-08",
+ "PR.PS-02",
+ "PR.PS-06"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "6.2",
+ "6.5",
+ "6.5.1-10"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "6.3.1",
+ "11.3.1",
+ "11.3.1.1"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "inspector2_is_enabled",
+ "inspector2_active_findings_exist"
+ ]
+ },
+ {
+ "Id": "BCR-08",
+ "Description": "Periodically backup data stored in the cloud. Ensure the confidentiality, integrity and availability of the backup, and verify data restoration from backup for resiliency.",
+ "Name": "Backup",
+ "Attributes": [
+ {
+ "Section": "Business Continuity Management and Operational Resilience",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "A1.2",
+ "A1.3"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "BCR-11"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "11.1",
+ "11.2",
+ "11.3",
+ "11.4",
+ "11.5"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.2.8",
+ "5.2.9"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "SY2.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.12.3",
+ "27017: 12.3",
+ "27018: 12.3.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.8.13",
+ "27001: A.5.23",
+ "27001: A.5.30",
+ "27002: 8.13",
+ "27002: 5.23 2nd (i)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "CP-4",
+ "CP-4(4)",
+ "CP-6",
+ "CP-6(1)-(3)",
+ "CP-9",
+ "CP-9(1)",
+ "CP-9(2)",
+ "CP-10",
+ "CP-10(2)",
+ "CP-10(4)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.IP-4",
+ "PR.DS-1"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.DS-01",
+ "PR.DS-11",
+ "RC.RP-03"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "9.5.1",
+ "12.10.1"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "12.10.1",
+ "10.3.3"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "backup_plans_exist",
+ "backup_vaults_exist",
+ "backup_vaults_encrypted",
+ "backup_recovery_point_encrypted",
+ "dynamodb_tables_pitr_enabled",
+ "dynamodb_table_protected_by_backup_plan",
+ "ec2_ebs_volume_snapshots_exists",
+ "ec2_ebs_volume_protected_by_backup_plan",
+ "efs_have_backup_enabled",
+ "rds_instance_backup_enabled",
+ "rds_instance_protected_by_backup_plan",
+ "rds_cluster_protected_by_backup_plan",
+ "redshift_cluster_automated_snapshot",
+ "s3_bucket_object_versioning",
+ "documentdb_cluster_backup_enabled",
+ "neptune_cluster_backup_enabled",
+ "elasticache_redis_cluster_backup_enabled",
+ "fsx_file_system_copy_tags_to_backups_enabled",
+ "lightsail_instance_automated_snapshots",
+ "dlm_ebs_snapshot_lifecycle_policy_exists"
+ ]
+ },
+ {
+ "Id": "BCR-09",
+ "Description": "Establish, document, approve, communicate, apply, evaluate and maintain a disaster response plan to recover from natural and man-made disasters. Update the plan at least annually or upon significant changes.",
+ "Name": "Disaster Response Plan",
+ "Attributes": [
+ {
+ "Section": "Business Continuity Management and Operational Resilience",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "A1.2",
+ "CC3.2"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.2.8",
+ "5.2.9",
+ "1.6.1",
+ "1.6.2",
+ "1.6.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "BC1.4",
+ "BC2.1",
+ "BC2.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.29",
+ "27001: A.5.30",
+ "27002: 5.29",
+ "27002: 5.30"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "CP-2(1)",
+ "CP-2(2)",
+ "CP-2(3)",
+ "CP-2(5)",
+ "CP-2(6)",
+ "CP-2(7)",
+ "CP-2(8)",
+ "PE-13",
+ "PE-13(1)",
+ "PE-13(2)",
+ "PE-13(4)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.IP-9",
+ "PR.IP-10",
+ "RC.IM-1",
+ "RC.IM-2"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "ID.IM-04"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "drs_job_exist",
+ "ssmincidents_enabled_with_plans"
+ ]
+ },
+ {
+ "Id": "BCR-11",
+ "Description": "Supplement business-critical equipment with redundant equipment independently located at a reasonable minimum distance in accordance with applicable industry standards.",
+ "Name": "Equipment Redundancy",
+ "Attributes": [
+ {
+ "Section": "Business Continuity Management and Operational Resilience",
+ "CCMLite": "No",
+ "IaaS": "CSP-Owned",
+ "PaaS": "CSP-Owned",
+ "SaaS": "CSP-Owned",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "A1.2",
+ "CC3.2"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "BCR-06"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.2.8"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "BC1.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.20",
+ "27001: A.7.11",
+ "27001: A.8.14",
+ "27002: 5.20 (t)",
+ "27002: 8.14 (c)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "CP-2",
+ "CP-2(2)",
+ "CP-4(3)",
+ "CP-6",
+ "CP-6(1)",
+ "CP-7",
+ "CP-8",
+ "CP-8(1)-(3)",
+ "CP-9",
+ "CP-9(6)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "ID.BE-4",
+ "ID.BE-5"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "GV.OC-04",
+ "GV.OC-05",
+ "PR.IR-03"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "rds_instance_multi_az",
+ "rds_cluster_multi_az",
+ "elbv2_is_in_multiple_az",
+ "elb_is_in_multiple_az",
+ "autoscaling_group_multiple_az",
+ "autoscaling_group_multiple_instance_types",
+ "ec2_ebs_volume_protected_by_backup_plan",
+ "elasticache_redis_cluster_multi_az_enabled",
+ "elasticache_redis_cluster_automatic_failover_enabled",
+ "opensearch_service_domains_fault_tolerant_data_nodes",
+ "opensearch_service_domains_fault_tolerant_master_nodes",
+ "dynamodb_accelerator_cluster_multi_az",
+ "documentdb_cluster_multi_az_enabled",
+ "neptune_cluster_multi_az",
+ "efs_multi_az_enabled",
+ "vpc_vpn_connection_tunnels_up",
+ "directconnect_connection_redundancy",
+ "directconnect_virtual_interface_redundancy",
+ "networkfirewall_multi_az",
+ "vpc_endpoint_multi_az_enabled",
+ "awslambda_function_vpc_multi_az",
+ "redshift_cluster_multi_az_enabled"
+ ]
+ },
+ {
+ "Id": "CCC-04",
+ "Description": "Restrict the unauthorized addition, removal, update, and management of organization assets.",
+ "Name": "Unauthorized Change Protection",
+ "Attributes": [
+ {
+ "Section": "Change Control and Configuration Management",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC8.1"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "CCC-04"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.2.1",
+ "1.3.4",
+ "5.3.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "SY2.4",
+ "SM2.6"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.12.1.4",
+ "27002: 12.1.4",
+ "27001: A.12.4.2",
+ "27002: 12.4.2",
+ "27001: A.14.2.2",
+ "27017: 14.2.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.8.3",
+ "27001: A.8.4",
+ "27001: A.8.15",
+ "27001: A.8.31",
+ "27001: A.8.32"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "CA-7",
+ "CA-7(4)",
+ "CM-3",
+ "CM-3(1)",
+ "CM-3(5)",
+ "CM-3(7)",
+ "CM-3(8)",
+ "CM-5",
+ "CM-5(1)",
+ "CM-5(4)",
+ "CM-5(5)",
+ "CM-6",
+ "CM-6(1)",
+ "CM-6(2)",
+ "CM-7",
+ "CM-7(1)",
+ "CM-7(4)",
+ "CM-7(5)",
+ "CM-7(9)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "ID.AM-1",
+ "ID.AM-2",
+ "ID.AM-4",
+ "PR.MA-1",
+ "PR.MA-2",
+ "PR.AC-1"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "ID.AM-01",
+ "ID.AM-02",
+ "ID.AM-04",
+ "ID.AM-08",
+ "PR.PS-02",
+ "PR.PS-03",
+ "PR.PS-05",
+ "PR.AA-05"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "6.4.5.2"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "6.5.1",
+ "6.5.2"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "cloudtrail_multi_region_enabled",
+ "cloudtrail_log_file_validation_enabled",
+ "s3_bucket_object_lock",
+ "cloudwatch_log_metric_filter_aws_organizations_changes",
+ "servicecatalog_portfolio_shared_within_organization_only"
+ ]
+ },
+ {
+ "Id": "CCC-07",
+ "Description": "Implement detection measures with proactive notification in case of changes deviating from the established baseline.",
+ "Name": "Detection of Baseline Deviation",
+ "Attributes": [
+ {
+ "Section": "Change Control and Configuration Management",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC8.1"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "GRM-01"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "1.5.1",
+ "1.5.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "SY2.4"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.14.2.2",
+ "27001: A.14.2.4",
+ "27001: A.12.4.1",
+ "27002: 12.4.1 (g)",
+ "27001: A.5.1.1",
+ "27017: 5.1.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.8.9",
+ "27001: A.8.15",
+ "27002: 8.9"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "CM-6",
+ "CM-6(2)",
+ "SI-2",
+ "SI-2(2)-(6)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.MA-1",
+ "PR.IP-1",
+ "DE.DP-4",
+ "PR.IP-3"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.PS-01",
+ "DE.CM-09",
+ "DE.AE-06"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "6.4.5.3",
+ "6.4.5.4",
+ "11.5",
+ "11.5.1"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "11.5.2",
+ "11.6.1"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "config_recorder_all_regions_enabled",
+ "guardduty_is_enabled",
+ "securityhub_enabled",
+ "cloudwatch_log_metric_filter_and_alarm_for_aws_config_configuration_changes_enabled",
+ "cloudwatch_log_metric_filter_and_alarm_for_cloudtrail_configuration_changes_enabled",
+ "cloudwatch_changes_to_network_acls_alarm_configured",
+ "cloudwatch_changes_to_network_gateways_alarm_configured",
+ "cloudwatch_changes_to_network_route_tables_alarm_configured",
+ "cloudwatch_log_metric_filter_authentication_failures",
+ "cloudwatch_log_metric_filter_aws_organizations_changes",
+ "cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk"
+ ]
+ },
+ {
+ "Id": "CEK-03",
+ "Description": "Provide cryptographic protection to data at-rest and in-transit, using cryptographic libraries certified to approved standards.",
+ "Name": "Data Encryption",
+ "Attributes": [
+ {
+ "Section": "Cryptography, Encryption & Key Management",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC6.1",
+ "CC6.7"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "EKM-03",
+ "EKM-04"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "3.6",
+ "3.1",
+ "3.11",
+ "11.3",
+ "16.11"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.1.1",
+ "5.1.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "TS2.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.18.1.1",
+ "27001: A.18.1.2",
+ "27001: A.18.1.3",
+ "27001: A.18.1.4",
+ "27001: A.18.1.5",
+ "27001: A.10.1",
+ "27002: 10.1",
+ "27001: A.13.2.1",
+ "27002: 13.2.1",
+ "27001: A.18",
+ "27002: 18",
+ "27001: A.14.1.2",
+ "27002: 14.1.2",
+ "27001: A.14.1.3",
+ "27002 14.1.3 c)",
+ "27001 - A.10.1.1",
+ "27017 - 10.1.1",
+ "27001 - A.10.1.2",
+ "27017 - 10.1.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.14",
+ "27001: A.8.24",
+ "27002: 8.24 Other Information (a)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "AC-19",
+ "AC-19(5)",
+ "SC-8",
+ "SC-8(1)",
+ "SC-8(3)",
+ "SC-8(4)",
+ "SC-12",
+ "SC-12(2)",
+ "SC-12(3)",
+ "SC-28",
+ "SC-28(1)-(3)",
+ "SI-4",
+ "SI-4(10)",
+ "SI-7",
+ "SI-7(6)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.DS-1",
+ "PR.DS-2"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.DS-01",
+ "PR.DS-02"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "Requirement 3",
+ "2.2.3",
+ "2.3",
+ "3.4",
+ "3.5.3",
+ "4.1",
+ "8.2.1",
+ "PCI Glossary - Strong Cryptography"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "2.2.7",
+ "3.5.1",
+ "4.2.1",
+ "4.2.1.2",
+ "4.2.2"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "ec2_ebs_volume_encryption",
+ "ec2_ebs_default_encryption",
+ "ec2_ebs_snapshots_encrypted",
+ "s3_bucket_default_encryption",
+ "s3_bucket_kms_encryption",
+ "s3_bucket_secure_transport_policy",
+ "rds_instance_storage_encrypted",
+ "rds_cluster_storage_encrypted",
+ "rds_instance_transport_encrypted",
+ "rds_snapshots_encrypted",
+ "efs_encryption_at_rest_enabled",
+ "dynamodb_tables_kms_cmk_encryption_enabled",
+ "dynamodb_accelerator_cluster_encryption_enabled",
+ "dynamodb_accelerator_cluster_in_transit_encryption_enabled",
+ "kinesis_stream_encrypted_at_rest",
+ "firehose_stream_encrypted_at_rest",
+ "sns_topics_kms_encryption_at_rest_enabled",
+ "sqs_queues_server_side_encryption_enabled",
+ "cloudtrail_kms_encryption_enabled",
+ "cloudwatch_log_group_kms_encryption_enabled",
+ "opensearch_service_domains_encryption_at_rest_enabled",
+ "opensearch_service_domains_node_to_node_encryption_enabled",
+ "opensearch_service_domains_https_communications_enforced",
+ "redshift_cluster_encrypted_at_rest",
+ "redshift_cluster_in_transit_encryption_enabled",
+ "documentdb_cluster_storage_encrypted",
+ "neptune_cluster_storage_encrypted",
+ "neptune_cluster_snapshot_encrypted",
+ "elasticache_redis_cluster_rest_encryption_enabled",
+ "elasticache_redis_cluster_in_transit_encryption_enabled",
+ "kafka_cluster_in_transit_encryption_enabled",
+ "kafka_cluster_encryption_at_rest_uses_cmk",
+ "kafka_connector_in_transit_encryption_enabled",
+ "dms_endpoint_ssl_enabled",
+ "dms_endpoint_redis_in_transit_encryption_enabled",
+ "elb_ssl_listeners",
+ "elbv2_ssl_listeners",
+ "elbv2_insecure_ssl_ciphers",
+ "elbv2_nlb_tls_termination_enabled",
+ "cloudfront_distributions_https_enabled",
+ "cloudfront_distributions_origin_traffic_encrypted",
+ "cloudfront_distributions_custom_ssl_certificate",
+ "transfer_server_in_transit_encryption_enabled",
+ "sagemaker_notebook_instance_encryption_enabled",
+ "sagemaker_training_jobs_volume_and_output_encryption_enabled",
+ "workspaces_volume_encryption_enabled",
+ "storagegateway_fileshare_encryption_enabled",
+ "backup_vaults_encrypted",
+ "backup_recovery_point_encrypted",
+ "athena_workgroup_encryption",
+ "glue_data_catalogs_connection_passwords_encryption_enabled",
+ "glue_data_catalogs_metadata_encryption_enabled",
+ "glue_etl_jobs_amazon_s3_encryption_enabled",
+ "glue_etl_jobs_cloudwatch_logs_encryption_enabled",
+ "glue_etl_jobs_job_bookmark_encryption_enabled",
+ "glue_development_endpoints_s3_encryption_enabled",
+ "glue_development_endpoints_cloudwatch_logs_encryption_enabled",
+ "glue_development_endpoints_job_bookmark_encryption_enabled",
+ "glue_ml_transform_encrypted_at_rest",
+ "bedrock_model_invocation_logs_encryption_enabled",
+ "codebuild_project_s3_logs_encrypted",
+ "codebuild_report_group_export_encrypted"
+ ]
+ },
+ {
+ "Id": "CEK-04",
+ "Description": "Use encryption algorithms that are appropriate for data protection, considering the classification of data, associated risks, and usability of the encryption technology.",
+ "Name": "Encryption Algorithm",
+ "Attributes": [
+ {
+ "Section": "Cryptography, Encryption & Key Management",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC6.1",
+ "CC6.7"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "EKM-04"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "16.11"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.1.1",
+ "5.1.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "TS2.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: 6.1.2",
+ "27001: 6.1.3",
+ "27001: A.8.2",
+ "27002: 8.2",
+ "27001: A.8.3",
+ "27001: A.10.1.1",
+ "27002: 10.1.1 (b)",
+ "27001: A.10.1.2",
+ "27002: 10.1.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: 6.1.2",
+ "27001: 6.1.3",
+ "27001: A.8.24",
+ "27001: A.5.12",
+ "27001: A.5.13",
+ "27002: 8.24 General (b)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "SC-12",
+ "SC-12(2)",
+ "SC-12(3)",
+ "SC-28",
+ "SC-28(1)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.DS-1",
+ "PR.DS-2",
+ "ID.AM-5"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.DS-01",
+ "PR.DS-02",
+ "ID.AM-05"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "A2",
+ "Requirement 3",
+ "2.3",
+ "2.2.3",
+ "3.4",
+ "3.5.3",
+ "4.1",
+ "8.2.1",
+ "PCI Glossary - Strong Cryptography"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "2.2.7",
+ "3.5.1",
+ "4.2.1",
+ "4.2.1.2",
+ "4.2.2"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "acm_certificates_with_secure_key_algorithms",
+ "elb_insecure_ssl_ciphers",
+ "elbv2_insecure_ssl_ciphers",
+ "cloudfront_distributions_using_deprecated_ssl_protocols"
+ ]
+ },
+ {
+ "Id": "CEK-08",
+ "Description": "CSPs must provide the capability for CSCs to manage their own data encryption keys.",
+ "Name": "CSC Key Management Capability",
+ "Attributes": [
+ {
+ "Section": "Cryptography, Encryption & Key Management",
+ "CCMLite": "No",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "TS2.2",
+ "SC2.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.10.1",
+ "27017: 10.1",
+ "27001: A.10.1.1",
+ "27017: 10.1.1",
+ "27001: A.10.1.2",
+ "27017: 10.1.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.23",
+ "27001: A.8.24"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "CP-9",
+ "CP-9(8)",
+ "SA-9",
+ "SA-9(6)",
+ "SC-12",
+ "SC-12(6)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "ID.SC-3",
+ "ID.AM-6",
+ "PR.AC-1"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "GV.SC-05"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "kms_cmk_are_used",
+ "s3_bucket_kms_encryption",
+ "dynamodb_tables_kms_cmk_encryption_enabled",
+ "kms_key_not_publicly_accessible",
+ "kms_cmk_not_multi_region"
+ ]
+ },
+ {
+ "Id": "CEK-10",
+ "Description": "Generate Cryptographic keys using industry accepted cryptographic libraries specifying the algorithm strength and the random number generator used.",
+ "Name": "Key Generation",
+ "Attributes": [
+ {
+ "Section": "Cryptography, Encryption & Key Management",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "EKM-04"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "16.11"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.1.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "TS2.2",
+ "TS2.3",
+ "SY1.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.10.1.1",
+ "27002: 10.1.1 (e)",
+ "27017: 10.1.1",
+ "27001: A.10.1.2",
+ "27002: 10.1.2",
+ "27002: 10.1.2 (a)",
+ "27017: 10.1.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.8.24",
+ "27002: 8.24 (d), Key management (a)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "SC-12",
+ "SC-12(2)",
+ "SC-12(3)",
+ "SC-13"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.AC-1"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.AA-01",
+ "PR.AA-05"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "2.2.3",
+ "3.6.1",
+ "PCI Glossary - Cryptographic Key Generation"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "3.6.1",
+ "3.6.1.1",
+ "3.7.1"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "kms_cmk_are_used"
+ ]
+ },
+ {
+ "Id": "CEK-12",
+ "Description": "Rotate cryptographic keys in accordance with the calculated cryptoperiod, which includes provisions for considering the risk of information disclosure and legal and regulatory requirements.",
+ "Name": "Key Rotation",
+ "Attributes": [
+ {
+ "Section": "Cryptography, Encryption & Key Management",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.1.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "TS2.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.10.1.1",
+ "27017: 10.1.1",
+ "27001: A.10.1.2",
+ "27002: 10.1.2 e)",
+ "27017: 10.1.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.31",
+ "27001: A.8.24",
+ "27002: 5.31 Cryptography",
+ "27002: 8.24 Key management (e,m)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "SC-12",
+ "SC-12(2)",
+ "SC-12(3)",
+ "SC-13"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.AC-1",
+ "ID.GV-3"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.AA-01",
+ "PR.AA-05",
+ "GV.OC-03"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "3.7.4",
+ "3.7.5"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "kms_cmk_rotation_enabled",
+ "iam_rotate_access_key_90_days",
+ "secretsmanager_automatic_rotation_enabled",
+ "secretsmanager_secret_rotated_periodically"
+ ]
+ },
+ {
+ "Id": "CEK-14",
+ "Description": "Define, implement and evaluate processes, procedures and technical measures to destroy keys stored outside a secure environment and revoke keys stored in Hardware Security Modules (HSMs) when they are no longer needed, which include provisions for legal and regulatory requirements.",
+ "Name": "Key Destruction",
+ "Attributes": [
+ {
+ "Section": "Cryptography, Encryption & Key Management",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.1.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "TS2.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.10.1.1",
+ "27017: 10.1.1",
+ "27017: 10.1.2",
+ "27001: A.10.1.2",
+ "27002: 10.1.2 (j)",
+ "27001: A.18.1.3",
+ "27002: 18.1.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.31",
+ "27001: A.8.24",
+ "27002: 5.31 Cryptography",
+ "27002: 8.24 Key management (j,m)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "SC-12",
+ "SC-12(2)",
+ "SC-12(3)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.AC-1",
+ "PR.IP-6",
+ "ID.GV-3",
+ "PR.DS-3"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.AA-01",
+ "PR.AA-05",
+ "ID.AM-08",
+ "GV.OC-03"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "3.6.4",
+ "3.6.5"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "3.7.4",
+ "3.7.5"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "kms_cmk_not_deleted_unintentionally"
+ ]
+ },
+ {
+ "Id": "DCS-06",
+ "Description": "Catalogue and track all relevant physical and logical assets located at all of the CSP's sites within a secured system.",
+ "Name": "Assets Cataloguing and Tracking",
+ "Attributes": [
+ {
+ "Section": "Datacenter Security",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC6.1"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "DCS - 01"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "1.1",
+ "2.1"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "1.3.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "SM2.6"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.8.1.1",
+ "27002: 8.1.1",
+ "27017: 8.1.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.9"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "CM-8",
+ "CM-8(1)",
+ "CM-8(2)",
+ "CM-8(4)",
+ "CM-8(7)",
+ "CM-8(8)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "ID.AM-1",
+ "ID.AM-2",
+ "ID.AM-4",
+ "PR.AC-4"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "ID.AM-01",
+ "ID.AM-02",
+ "ID.AM-04"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "2.4",
+ "9.7.1",
+ "9.9.1",
+ "9.9.1.a",
+ "9.9.1.b",
+ "9.9.1.c",
+ "12.3.3",
+ "12.3.4"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "3.6.1.1",
+ "6.3.2",
+ "9.4.2",
+ "9.4.3",
+ "12.5.1"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "config_recorder_all_regions_enabled",
+ "resourceexplorer2_indexes_found"
+ ]
+ },
+ {
+ "Id": "DSP-02",
+ "Description": "Apply industry accepted methods for the secure disposal of data from storage media such that data is not recoverable by any forensic means.",
+ "Name": "Secure Disposal",
+ "Attributes": [
+ {
+ "Section": "Data Security and Privacy Lifecycle Management",
+ "CCMLite": "No",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC6.1",
+ "CC6.2",
+ "CC6.3",
+ "CC6.4",
+ "CC6.5",
+ "CC6.7",
+ "P4.3"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "DSI-07"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "3.5"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.1.1",
+ "5.3.3",
+ "7.1.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "IM1.1",
+ "IM1.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.8.3.2",
+ "27002: 8.3.2",
+ "27001: A.11.2.7",
+ "27002: 11.2.7"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.7.10",
+ "27001: A.7.14",
+ "27001: A.8.10",
+ "27002: 7.10 (Secure reuse or disposal)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "PM-22",
+ "SI-12",
+ "SI-12(3)",
+ "SI-18",
+ "SI-18(1)",
+ "SI-18(4)",
+ "SI-18(5)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.IP-6"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "GV.SC-10",
+ "PR.PS-02",
+ "PR.PS-03",
+ "ID.AM-08"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "3.1",
+ "9.8",
+ "9.8.1",
+ "9.8.2"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "3.2.1",
+ "3.7.5",
+ "9.4.7"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "s3_bucket_lifecycle_enabled",
+ "dlm_ebs_snapshot_lifecycle_policy_exists",
+ "ecr_repositories_lifecycle_policy_enabled"
+ ]
+ },
+ {
+ "Id": "DSP-03",
+ "Description": "Create and maintain a data inventory, at least for any sensitive data and personal data.",
+ "Name": "Data Inventory",
+ "Attributes": [
+ {
+ "Section": "Data Security and Privacy Lifecycle Management",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC6.1"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "3.2"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "1.3.1",
+ "1.3.2",
+ "1.3.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "IM1.1",
+ "IM2.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.8.1.1",
+ "27002: 8.1.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.9",
+ "27001: A.8.12"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "CM-12",
+ "CM-12(1)",
+ "PM-5",
+ "PM-5(1)",
+ "SI-12",
+ "SI-12(1)",
+ "SI-19",
+ "SI-19(1)",
+ "SI-19(2)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "ID.AM-5"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "ID.AM-07"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "3.2.1",
+ "9.4.5"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "macie_is_enabled",
+ "macie_automated_sensitive_data_discovery_enabled",
+ "config_recorder_all_regions_enabled"
+ ]
+ },
+ {
+ "Id": "DSP-04",
+ "Description": "Classify data according to its type and sensitivity level.",
+ "Name": "Data Classification",
+ "Attributes": [
+ {
+ "Section": "Data Security and Privacy Lifecycle Management",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC6.1",
+ "C1.1"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "DSI-01"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "3.7"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "1.3.1",
+ "1.3.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "IM1.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.8.2.1",
+ "27002: 8.2.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.12"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "AC-16",
+ "AC-16(9)",
+ "PM-22",
+ "PM-23",
+ "PT-2",
+ "PT-2(1)",
+ "SI-18",
+ "SI-18(2)",
+ "SI-19",
+ "SI-19(6)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "ID.AM-5"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "ID.AM-05",
+ "ID.AM-07"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "9.6.1"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "9.4.2",
+ "9.4.3"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "macie_is_enabled",
+ "macie_automated_sensitive_data_discovery_enabled"
+ ]
+ },
+ {
+ "Id": "DSP-07",
+ "Description": "Develop systems, products, and business practices based upon a principle of security by design and industry best practices.",
+ "Name": "Data Protection by Design and Default",
+ "Attributes": [
+ {
+ "Section": "Data Security and Privacy Lifecycle Management",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "PI1.2",
+ "PI1.3"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "16.1"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.3.1",
+ "5.3.2",
+ "5.3.3",
+ "5.3.4"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "SD2.2",
+ "IM1.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.14.1.1",
+ "27002:14.1.1",
+ "27001: A.14.2.5",
+ "27002:14.2.5"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.8.27",
+ "27001: A.8.28",
+ "27001: A.8.29",
+ "27002: 5.8 (Information security requirements a-i)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "PM-17",
+ "PM-24",
+ "PM-25",
+ "PT-2",
+ "PT-2(2)",
+ "SA-3",
+ "SA-4",
+ "SA-5",
+ "SA-8",
+ "SA-8(9)",
+ "SA-8(13)",
+ "SA-8(18)",
+ "SA-8(20)",
+ "SA-8(22)",
+ "SA-8(23)",
+ "SA-8(33)",
+ "SA-15",
+ "SA-15(12)",
+ "SC-3",
+ "SC-3(3)",
+ "SC-7",
+ "SC-7(24)",
+ "SC-8",
+ "SC-8(1)-(4)",
+ "SC-28",
+ "SC-28(1)",
+ "SI-12",
+ "SI-12(1)-(3)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.IP-2",
+ "PR.PT-3",
+ "PR.AC-4"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "ID.AM-08",
+ "PR.PS-06"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "6.2.1"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "ec2_ebs_default_encryption",
+ "s3_account_level_public_access_blocks",
+ "s3_bucket_level_public_access_block",
+ "ec2_ebs_snapshot_account_block_public_access",
+ "rds_instance_no_public_access",
+ "rds_snapshots_public_access"
+ ]
+ },
+ {
+ "Id": "DSP-10",
+ "Description": "Define, implement and evaluate processes, procedures and technical measures that ensure any transfer of personal or sensitive data is protected from unauthorized access and only processed within scope as permitted by the respective laws and regulations.",
+ "Name": "Sensitive Data Transfer",
+ "Attributes": [
+ {
+ "Section": "Data Security and Privacy Lifecycle Management",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC6.7"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "GRM-02",
+ "EKM-03"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "3.1",
+ "3.12",
+ "3.13"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.1.2",
+ "9.5.1",
+ "9.5.2",
+ "9.5.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "IM1.4",
+ "IM2.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.13.2.1",
+ "27002: 13.2.1",
+ "27001: A.8.3.3",
+ "27002: 8.3.3",
+ "27001: A.13.2.3",
+ "27002: 13.2.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.14",
+ "27001: A.7.10"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "AC-4",
+ "AC-4(23)-(25)",
+ "CA-3",
+ "CA-3(6)",
+ "CA-6",
+ "CA-6(1)",
+ "CA-6(2)",
+ "SC-4",
+ "SC-4(2)",
+ "SC-7",
+ "SC-7(10)",
+ "SC-7(24)",
+ "SC-8",
+ "SC-8(1)-(5)",
+ "SC-16",
+ "SC-16(1)-(3)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.DS-2",
+ "PR.DS-5",
+ "PR.PT-4"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.DS-02",
+ "PR.IR-01",
+ "ID.AM-03",
+ "GV.OC-03",
+ "ID.AM-07"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "4.1"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "4.1.1",
+ "4.2.1",
+ "4.2.2"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "s3_bucket_secure_transport_policy",
+ "opensearch_service_domains_https_communications_enforced",
+ "redshift_cluster_in_transit_encryption_enabled",
+ "rds_instance_transport_encrypted",
+ "transfer_server_in_transit_encryption_enabled",
+ "kafka_cluster_mutual_tls_authentication_enabled"
+ ]
+ },
+ {
+ "Id": "DSP-16",
+ "Description": "Data retention, archiving and deletion is managed in accordance with business requirements, applicable laws and regulations.",
+ "Name": "Data Retention and Deletion",
+ "Attributes": [
+ {
+ "Section": "Data Security and Privacy Lifecycle Management",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "C1.1",
+ "C1.2",
+ "CC3.1",
+ "P4.2"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "GRM-02",
+ "BCR-11"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "3.4",
+ "3.5"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.1.1",
+ "5.3.1",
+ "7.1.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "IM1.1",
+ "IM2.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.18.1.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.33",
+ "27001: A.8.10",
+ "27002: 5.33 (b)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "SI-12",
+ "SI-12(1)-(3)",
+ "SI-18",
+ "SI-18(1)",
+ "SI-18(4)",
+ "SI-18(5)",
+ "SI-19",
+ "SI-19(2)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.DS-3",
+ "PR.IP-6",
+ "ID.GV-3"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "ID.AM-08",
+ "GV.OC-03",
+ "GV.SC-10",
+ "PR.DS-11"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "3.1"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "3.2.1"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "s3_bucket_lifecycle_enabled",
+ "cloudwatch_log_group_retention_policy_specific_days_enabled",
+ "kinesis_stream_data_retention_period",
+ "ecr_repositories_lifecycle_policy_enabled"
+ ]
+ },
+ {
+ "Id": "DSP-17",
+ "Description": "Define and implement, processes, procedures and technical measures to protect sensitive data throughout it's lifecycle.",
+ "Name": "Sensitive Data Protection",
+ "Attributes": [
+ {
+ "Section": "Data Security and Privacy Lifecycle Management",
+ "CCMLite": "Yes",
+ "IaaS": "CSP-Owned",
+ "PaaS": "CSP-Owned",
+ "SaaS": "CSC-Owned",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC2.1",
+ "CC6.1",
+ "CC6.3",
+ "CC6.7",
+ "CC8.1",
+ "C1.1",
+ "P2.0",
+ "P3.0",
+ "P4.0",
+ "P5.0",
+ "P6.0"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "3.1",
+ "3.1",
+ "3.14"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.3.3",
+ "9.1.1",
+ "9.2.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "IM1.1",
+ "IM2.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.18.1.3",
+ "27002: 18.1.3",
+ "27001:A.18.1.4",
+ "27002:18.1.4"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.8.11",
+ "27001: A.8.12"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "PL-2",
+ "PM-22",
+ "PM-24",
+ "PT-7",
+ "PT-7(1)",
+ "PT-7(2)",
+ "PT-8",
+ "SC-8",
+ "SC-8(1)-(5)",
+ "SC-28",
+ "SC-28(1)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.DS-1",
+ "PR.DS-2",
+ "PR.DS-5"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.DS-01",
+ "PR.DS-02",
+ "PR.DS-10"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "3.0 (including all subsections)",
+ "4.0 (including all subsections)"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "3.1.1",
+ "4.1.1"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "s3_account_level_public_access_blocks",
+ "s3_bucket_public_access",
+ "s3_bucket_policy_public_write_access",
+ "ec2_ebs_public_snapshot",
+ "rds_snapshots_public_access",
+ "rds_instance_no_public_access",
+ "ec2_ebs_volume_encryption",
+ "s3_bucket_default_encryption",
+ "rds_instance_storage_encrypted",
+ "secretsmanager_not_publicly_accessible",
+ "macie_is_enabled"
+ ]
+ },
+ {
+ "Id": "GRC-05",
+ "Description": "Develop and implement an Information Security Program, which includes programs for all the relevant domains of the CCM.",
+ "Name": "Information Security Program",
+ "Attributes": [
+ {
+ "Section": "Governance, Risk and Compliance",
+ "CCMLite": "No",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "GRM-04"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "14.1"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "1.2.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "SG2.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: 4.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: 4.3"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "PM-1",
+ "PM-3",
+ "PM-14",
+ "PL-2",
+ "PM-18",
+ "PM-31"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "12.4.1",
+ "A.3.1"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "12.4.1",
+ "A3.1.1"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "securityhub_enabled",
+ "guardduty_is_enabled"
+ ]
+ },
+ {
+ "Id": "IAM-02",
+ "Description": "Establish, document, approve, communicate, implement, apply, evaluate and maintain strong password policies and procedures. Review and update the policies and procedures at least annually.",
+ "Name": "Strong Password Policy and Procedures",
+ "Attributes": [
+ {
+ "Section": "Identity & Access Management",
+ "CCMLite": "No",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "IAM-02",
+ "IAM-12",
+ "GRM-06",
+ "GRM-09"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "5.2"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "1.1.1",
+ "1.5.1",
+ "4.1.2",
+ "4.1.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "SA1.1",
+ "SA1.5"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: 5.1",
+ "27001: 5.2",
+ "27001: 7.3",
+ "27001: 7.4",
+ "27001: 7.5",
+ "27001: 9.1",
+ "27001: 9.3",
+ "27001: A.5",
+ "27002: 5",
+ "27001: A.9.4.3",
+ "27002: 9.4.3",
+ "27017: 9.4.3",
+ "27018: 9.4.3",
+ "27001: A.9.2.4",
+ "27002: 9.2.4",
+ "27017: 9.2.4",
+ "27001: A.7.2.2",
+ "27002: 7.2.2",
+ "27001: A.9.2.6",
+ "27002: 9.2.6",
+ "27001: A.9.2.3",
+ "27002: 9.2.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: 5.1",
+ "27001: 5.2",
+ "27001: 7.3",
+ "27001: 7.4",
+ "27001: 7.5",
+ "27001: 9.1",
+ "27001: 9.3",
+ "27001: A.5.1",
+ "27001: A.5.4",
+ "27001: A.5.17",
+ "27001: A.6.3",
+ "27001: A.8.5",
+ "27001: A.5.37"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "AC-2",
+ "AC-2(3)",
+ "AC-2(11)",
+ "AC-3",
+ "AC-3(3)",
+ "AC-12",
+ "AC-12(1)",
+ "IA-2",
+ "IA-2(10)",
+ "IA-5",
+ "IA-5(1)",
+ "IA-5(18)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "ID.GV-1",
+ "PR.AC-1",
+ "PR.AC-7"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "GV.PO-01",
+ "GV.PO-02",
+ "ID.IM-03",
+ "PR.AA-03"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "8.4",
+ "12.1",
+ "12.1.1",
+ "12.11"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "8.1.1",
+ "8.3.8"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "iam_password_policy_minimum_length_14",
+ "iam_password_policy_lowercase",
+ "iam_password_policy_uppercase",
+ "iam_password_policy_number",
+ "iam_password_policy_symbol",
+ "iam_password_policy_reuse_24",
+ "iam_password_policy_expires_passwords_within_90_days_or_less",
+ "cognito_user_pool_password_policy_minimum_length_14",
+ "cognito_user_pool_password_policy_lowercase",
+ "cognito_user_pool_password_policy_uppercase",
+ "cognito_user_pool_password_policy_number",
+ "cognito_user_pool_password_policy_symbol"
+ ]
+ },
+ {
+ "Id": "IAM-03",
+ "Description": "Manage, store, and review the information of system identities, and level of access.",
+ "Name": "Identity Inventory",
+ "Attributes": [
+ {
+ "Section": "Identity & Access Management",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC6.1",
+ "CC6.3"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "IAM-04",
+ "IAM-08",
+ "IAM-10"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "5.1",
+ "5.2"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "4.1.3",
+ "4.2.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "SA1.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: 9.2 (c)",
+ "27001: A.8.1.1",
+ "27002: 8.1.1",
+ "27001: A.9.4.1",
+ "27002: 9.4.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: 9.2 (c)",
+ "27001: A.5.15",
+ "27001: A.5.16",
+ "27001: A.5.18",
+ "27001: A.7.4",
+ "27001: A.8.15",
+ "27001: A.8.2",
+ "27001: A.8.3"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "AU-10",
+ "AU-10(1)",
+ "AU-10(2)",
+ "AU-16",
+ "AU-16(1)",
+ "IA-4",
+ "IA-4(8)",
+ "IA-4(9)",
+ "IA-5",
+ "IA-5(5)",
+ "IA-8",
+ "IA-8(4)",
+ "PM-5(1)",
+ "SA-8",
+ "SA-8(22)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.AC-1",
+ "PR.AC-6",
+ "PR.AC-4"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.AA-01",
+ "PR.AA-02",
+ "PR.AA-04",
+ "PR.AA-05"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "2.4.a"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "7.2.5",
+ "7.2.5.1"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "iam_user_accesskey_unused",
+ "iam_user_console_access_unused",
+ "iam_user_two_active_access_key"
+ ]
+ },
+ {
+ "Id": "IAM-04",
+ "Description": "Employ the separation of duties principle when implementing information system access.",
+ "Name": "Separation of Duties",
+ "Attributes": [
+ {
+ "Section": "Identity & Access Management",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC1.3",
+ "CC5.1",
+ "CC6.3"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "IAM-05"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "6.8"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "1.2.2",
+ "4.2.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "SA1.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.6.1.2",
+ "27002: 6.1.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.15",
+ "27001: A.5.18",
+ "27001: A.5.3",
+ "27001: A.8.2"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "AC-2",
+ "AC-2(3)",
+ "AC-2(11)",
+ "AC-6",
+ "AC-6(1)-(10)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.AC-4"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.AA-05"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "6.4",
+ "6.4.2"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "6.5.3",
+ "6.5.4",
+ "7.2.1",
+ "7.2.2"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "iam_policy_attached_only_to_group_or_roles",
+ "iam_securityaudit_role_created",
+ "iam_support_role_created"
+ ]
+ },
+ {
+ "Id": "IAM-05",
+ "Description": "Employ the least privilege principle when implementing information system access.",
+ "Name": "Least Privilege",
+ "Attributes": [
+ {
+ "Section": "Identity & Access Management",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC6.3"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "IAM-02",
+ "IAM-06",
+ "IVS-11"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "6.8"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "4.2.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "SA1.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.9.1.1",
+ "27002: 9.1.1",
+ "27001: A.9.1.2",
+ "27002: 9.1.2",
+ "27001: A.9.2.3",
+ "27002: 9.2.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.15",
+ "27001: A.8.2",
+ "27002: 5.15 (Other information 2nd (a))"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "AC-6",
+ "AC-6(4)",
+ "IA-12",
+ "IA-12(2)",
+ "IA-12(3)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.AC-4"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.AA-05"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "7.1",
+ "7.1.1",
+ "7.1.2"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "7.2.1",
+ "7.2.2",
+ "7.2.5",
+ "7.2.6"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "iam_aws_attached_policy_no_administrative_privileges",
+ "iam_customer_attached_policy_no_administrative_privileges",
+ "iam_inline_policy_no_administrative_privileges",
+ "iam_customer_unattached_policy_no_administrative_privileges",
+ "iam_policy_allows_privilege_escalation",
+ "iam_inline_policy_allows_privilege_escalation",
+ "iam_no_custom_policy_permissive_role_assumption",
+ "iam_role_administratoraccess_policy",
+ "iam_user_administrator_access_policy",
+ "iam_group_administrator_access_policy",
+ "iam_administrator_access_with_mfa"
+ ]
+ },
+ {
+ "Id": "IAM-07",
+ "Description": "De-provision or respectively modify access of movers / leavers or system identity changes in a timely manner in order to effectively adopt and communicate identity and access management policies.",
+ "Name": "User Access Changes and Revocation",
+ "Attributes": [
+ {
+ "Section": "Identity & Access Management",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC5.3",
+ "CC6.3"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "IAM-11"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "5.3",
+ "6.2"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "4.2.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "SA1.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.15",
+ "27001: A.5.18"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "AC-2",
+ "AC-2(1)",
+ "AC-2(2)",
+ "AC-2(6)",
+ "AC-2(8)",
+ "AC-3",
+ "AC-3(8)",
+ "AC-6",
+ "AC-6(7)",
+ "AU-10",
+ "AU-10(4)",
+ "AU-16",
+ "AU-16(1)",
+ "CM-7",
+ "CM-7(1)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.AC-1",
+ "PR.AC-4",
+ "PR.IP-11"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "GV.RR-04",
+ "GV.SC-10",
+ "PR.AA-01",
+ "PR.AA-05"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "8.1.2",
+ "8.1.3"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "8.2.5",
+ "8.2.6"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "iam_user_accesskey_unused",
+ "iam_user_console_access_unused",
+ "iam_user_no_setup_initial_access_key"
+ ]
+ },
+ {
+ "Id": "IAM-08",
+ "Description": "Review and revalidate user access for least privilege and separation of duties with a frequency that is commensurate with organizational risk tolerance.",
+ "Name": "User Access Review",
+ "Attributes": [
+ {
+ "Section": "Identity & Access Management",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC6.2",
+ "CC6.3"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "IAM-10"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "5.1"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "4.2.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "SA1.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.9.2.5",
+ "27001: A.9.2.6",
+ "27001: A.9.4.1",
+ "27017: 9.4.1",
+ "27001: A.6.1.2",
+ "27001: A 9.2.5"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.3",
+ "27001: A.5.18",
+ "27001: A.8.3"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "AC-6",
+ "AC-6(4)",
+ "AC-6(8)",
+ "IA-8",
+ "IA-8(4)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.AC-4"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.AA-05"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "12.5.5"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "7.2.5.1",
+ "7.2.5",
+ "7.2.4"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "iam_user_accesskey_unused",
+ "iam_user_console_access_unused",
+ "iam_rotate_access_key_90_days",
+ "secretsmanager_secret_unused"
+ ]
+ },
+ {
+ "Id": "IAM-09",
+ "Description": "Define, implement and evaluate processes, procedures and technical measures for the segregation of privileged access roles such that administrative access to data, encryption and key management capabilities and logging capabilities are distinct and separated.",
+ "Name": "Segregation of Privileged Access Roles",
+ "Attributes": [
+ {
+ "Section": "Identity & Access Management",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC5.1",
+ "CC6.1",
+ "CC6.3"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "5.4"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "SA1.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.9.2.3",
+ "27002: 9.2.3",
+ "27017: 9.2.3",
+ "27018: 9.2.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.8.2",
+ "27001: A.8.18",
+ "27002: 8.2 (j)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "AC-6",
+ "AC-3(7)",
+ "AC-6(4)",
+ "AC-6(8)",
+ "IA-5",
+ "IA-5(6)",
+ "IA-8",
+ "IA-8(4)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.AC-1",
+ "PR.AC-4"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.AA-01",
+ "PR.AA-05"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "2.3",
+ "3.5.2",
+ "7.1.2",
+ "7.1.1"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "3.6.1",
+ "3.7.6",
+ "6.5.3",
+ "6.5.4",
+ "7.2.1",
+ "7.2.2",
+ "10.3.1"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "iam_policy_attached_only_to_group_or_roles",
+ "iam_role_administratoraccess_policy",
+ "iam_avoid_root_usage",
+ "iam_no_root_access_key"
+ ]
+ },
+ {
+ "Id": "IAM-10",
+ "Description": "Define and implement an access process to ensure privileged access roles and rights are granted for a time limited period, and implement procedures to prevent the culmination of segregated privileged access.",
+ "Name": "Management of Privileged Access Roles",
+ "Attributes": [
+ {
+ "Section": "Identity & Access Management",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC6.1",
+ "CC6.2",
+ "CC6.3"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "5.1",
+ "6.5"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "SA1.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.9.2.3",
+ "27002: 9.2.3",
+ "27017: 9.2.3",
+ "27018: 9.2.3",
+ "27001: A.9.4.4",
+ "27002: 9.4.4",
+ "27017: 9.4.4"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.8.2",
+ "27001: A.8.18",
+ "27002: 8.2 (i)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "AC-2",
+ "AC-2(7)",
+ "AC-3",
+ "AC-3(4)",
+ "AC-3(11)",
+ "AC-3(13)",
+ "AC-3(14)",
+ "AC-6",
+ "AC-6(4)",
+ "AC-6(5)",
+ "AC-6(8)",
+ "AC-12",
+ "AC-12(3)",
+ "AC-17",
+ "AC-17(4)",
+ "IA-8",
+ "IA-8(4)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.AC-4"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.AA-05"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "7.1"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "7.2.1",
+ "7.2.2"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "iam_avoid_root_usage",
+ "iam_no_root_access_key",
+ "iam_role_cross_account_readonlyaccess_policy",
+ "iam_role_cross_service_confused_deputy_prevention",
+ "iam_inline_policy_allows_privilege_escalation",
+ "iam_policy_allows_privilege_escalation"
+ ]
+ },
+ {
+ "Id": "IAM-12",
+ "Description": "Define, implement and evaluate processes, procedures and technical measures to ensure the logging infrastructure is read-only for all with write access, including privileged access roles, and that the ability to disable it is controlled through a procedure that ensures the segregation of duties and break glass procedures.",
+ "Name": "Safeguard Logs Integrity",
+ "Attributes": [
+ {
+ "Section": "Identity & Access Management",
+ "CCMLite": "No",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "3.3"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "4.2.1",
+ "5.2.4"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "TM1.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.12.4.1",
+ "27002: 12.4.1",
+ "27017: 12.4.1",
+ "27018: 12.4.1",
+ "27001: A.12.4.2",
+ "27002: 12.4.2",
+ "27017: 12.4.2",
+ "27018: 12.4.2",
+ "27001: A.12.4.3",
+ "27002: 12.4.3",
+ "27017: 12.4.3",
+ "27018: 12.4.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.8.15",
+ "27001: A.8.18",
+ "27002: 8.15 Protection of Logs"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "AC-2",
+ "AC-2(11)",
+ "AC-2(12)",
+ "IA-8",
+ "IA-8(4)",
+ "SA-8",
+ "SA-8(22)",
+ "SC-34",
+ "SC-34(1)",
+ "SC-34(2)",
+ "SC-36",
+ "SI-4",
+ "SI-4(5)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.AC-4"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.AA-05"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "10.5"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "10.3.1",
+ "10.3.2",
+ "10.3.3",
+ "10.3.4"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "cloudtrail_log_file_validation_enabled",
+ "cloudtrail_logs_s3_bucket_is_not_publicly_accessible",
+ "cloudtrail_logs_s3_bucket_access_logging_enabled",
+ "cloudtrail_kms_encryption_enabled",
+ "cloudtrail_bucket_requires_mfa_delete"
+ ]
+ },
+ {
+ "Id": "IAM-13",
+ "Description": "Define, implement and evaluate processes, procedures and technical measures that ensure users are identifiable through unique IDs or which can associate individuals to the usage of user IDs.",
+ "Name": "Uniquely Identifiable Users",
+ "Attributes": [
+ {
+ "Section": "Identity & Access Management",
+ "CCMLite": "No",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC6.1"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "4.1.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "SA1.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.9.2.1",
+ "27002: 9.2.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.16"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "AC-3",
+ "AC-3(14)",
+ "AC-24",
+ "AC-24(2)",
+ "AU-10",
+ "AU-10(1)",
+ "IA-2",
+ "IA-2(1)",
+ "IA-2(2)",
+ "IA-2(12)",
+ "IA-4",
+ "IA-4(1)",
+ "SA-8",
+ "SA-8(22)",
+ "SC-23",
+ "SC-23(3)",
+ "SC-40(4)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.AC-1",
+ "PR.AC-6"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.AA-01",
+ "PR.AA-02"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "8.1",
+ "8.2",
+ "8.6"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "8.2.1",
+ "8.2.2",
+ "8.2.4"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "iam_user_mfa_enabled_console_access",
+ "iam_check_saml_providers_sts"
+ ]
+ },
+ {
+ "Id": "IAM-14",
+ "Description": "Define, implement and evaluate processes, procedures and technical measures for authenticating access to systems, application and data assets, including multifactor authentication for at least privileged user and sensitive data access. Adopt digital certificates or alternatives which achieve an equivalent level of security for system identities.",
+ "Name": "Strong Authentication",
+ "Attributes": [
+ {
+ "Section": "Identity & Access Management",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC6.1",
+ "CC6.2"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "IAM-02",
+ "IAM-05"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "6.3",
+ "6.5",
+ "12.5",
+ "12.7"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "4.1.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "SA1.3",
+ "SA1.4",
+ "SA1.8"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.9.1.2",
+ "27002: 9.1.2",
+ "27017: 9.1.2",
+ "27001: A.9.2.4",
+ "27002: 9.2.4",
+ "27017: 9.2.4",
+ "27001: A.9.4.2",
+ "27002: 9.4.2",
+ "27017: 9.4.2",
+ "27018: 9.4.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.15",
+ "27001: A.5.17",
+ "27001: A.8.5",
+ "27001: A.8.24",
+ "27002: 8.5",
+ "27002: 8.24 other information (d)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "AC-6",
+ "AC-6(5)",
+ "AC-7",
+ "AC-7(4)",
+ "AU-10",
+ "AU-10(2)",
+ "IA-2",
+ "IA-2(1)",
+ "IA-2(2)",
+ "IA-2(8)",
+ "IA-2(12)",
+ "IA-3",
+ "IA-3(1)",
+ "IA-5",
+ "IA-5(2)",
+ "IA-5(7)",
+ "IA-5(9)",
+ "IA-5(10)",
+ "IA-5(12)",
+ "IA-5(14)-(16)",
+ "IA-8",
+ "IA-8(1)",
+ "IA-8(6)",
+ "SC-23",
+ "SC-23(3)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.AC-1",
+ "PR.AC-6",
+ "PR.AC-7"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.AA-01",
+ "PR.AA-02",
+ "PR.AA-03"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "8.1.2",
+ "8.1.3",
+ "8.1.6",
+ "8.2",
+ "8.3",
+ "8.3.2",
+ "12.3.2"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "7.2.1",
+ "8.3.1",
+ "8.3.2",
+ "8.4.1",
+ "8.4.2",
+ "8.4.3"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "iam_root_mfa_enabled",
+ "iam_root_hardware_mfa_enabled",
+ "iam_user_mfa_enabled_console_access",
+ "iam_user_hardware_mfa_enabled",
+ "cognito_user_pool_mfa_enabled"
+ ]
+ },
+ {
+ "Id": "IAM-15",
+ "Description": "Define, implement and evaluate processes, procedures and technical measures for the secure management of passwords.",
+ "Name": "Passwords Management",
+ "Attributes": [
+ {
+ "Section": "Identity & Access Management",
+ "CCMLite": "No",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC6.1",
+ "CC6.2"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "4.1.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "SA1.5"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.9.2.4",
+ "27002: 9.2.4",
+ "27017: 9.2.4",
+ "27018: 9.2.4",
+ "27001: A.9.3.1",
+ "27002: 9.3.1",
+ "27017: 9.3.1",
+ "27018: 9.3.1",
+ "27001: A.9.4.3",
+ "27002: 9.4.3",
+ "27017: 9.4.3",
+ "27018: 9.4.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.17"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "IA-4",
+ "IA-4(8)",
+ "IA-5",
+ "IA-5(1)",
+ "IA-5(8)",
+ "IA-5(18)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.AC-1"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.AA-01"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "8.2",
+ "8.2.1-6"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "2.2.2",
+ "2.3.1",
+ "8.3.5",
+ "8.3.6",
+ "8.3.7",
+ "8.3.8",
+ "8.3.9",
+ "8.3.10",
+ "8.3.10.1",
+ "8.6.2"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "iam_password_policy_minimum_length_14",
+ "iam_password_policy_reuse_24",
+ "iam_password_policy_expires_passwords_within_90_days_or_less",
+ "cognito_user_pool_password_policy_minimum_length_14",
+ "cognito_user_pool_temporary_password_expiration"
+ ]
+ },
+ {
+ "Id": "IAM-16",
+ "Description": "Define, implement and evaluate processes, procedures and technical measures to verify access to data and system functions is authorized.",
+ "Name": "Authorization Mechanisms",
+ "Attributes": [
+ {
+ "Section": "Identity & Access Management",
+ "CCMLite": "No",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC6.1",
+ "CC6.2",
+ "CC6.3"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "IAM-02"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "5.1"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "4.2.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "SA1.3",
+ "SA1.4"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.9.2.5",
+ "27002: 9.2.5",
+ "27017: 9.2.5",
+ "27018: 9.2.5"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.18"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "AC-3",
+ "AC-3(5)",
+ "AC-4",
+ "AC-4(17)",
+ "AC-4(21)",
+ "AC-4(22)",
+ "AC-6",
+ "AC-6(8)",
+ "AC-6(9)",
+ "AC-12",
+ "AC-12(1)",
+ "AC-20",
+ "AC-20(1)",
+ "AU-10",
+ "AU-10(1)",
+ "AU-10(2)",
+ "IA-2",
+ "IA-2(1)",
+ "IA-2(2)",
+ "IA-2(12)",
+ "IA-3",
+ "IA-3(1)",
+ "IA-5(1)",
+ "IA-5(2)",
+ "IA-5(5)",
+ "IA-5(8)",
+ "IA-5(10)",
+ "IA-5(12)",
+ "IA-8",
+ "IA-8(1)",
+ "IA-8(2)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.AC-1",
+ "PR.AC-4",
+ "PR.AC-6",
+ "PR.AC-7",
+ "PR.PT-1"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.AA-01",
+ "PR.AA-02",
+ "PR.AA-03",
+ "PR.AA-04",
+ "PR.AA-05",
+ "PR.PS-04"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "5.3",
+ "7.1.4"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "7.2.4",
+ "7.2.3",
+ "7.2.5.1"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "iam_aws_attached_policy_no_administrative_privileges",
+ "iam_customer_attached_policy_no_administrative_privileges",
+ "iam_inline_policy_no_administrative_privileges",
+ "apigateway_restapi_authorizers_enabled",
+ "apigatewayv2_api_authorizers_enabled",
+ "awslambda_function_not_publicly_accessible",
+ "awslambda_function_url_public",
+ "cognito_user_pool_waf_acl_attached"
+ ]
+ },
+ {
+ "Id": "IPY-03",
+ "Description": "Implement cryptographically secure and standardized network protocols for the management, import and export of data.",
+ "Name": "Secure Interoperability and Portability Management",
+ "Attributes": [
+ {
+ "Section": "Interoperability & Portability",
+ "CCMLite": "No",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC6.7"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "IPY-04"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.1.1",
+ "5.1.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "SY1.1",
+ "SY1.2",
+ "NC1.4"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.18.1",
+ "27001: A.15.1.1",
+ "27002: 15.1.1",
+ "27017: 15.1.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.19",
+ "27001: A.5.23",
+ "27001: A.5.31",
+ "27001: A.5.32",
+ "27001: A.5.33",
+ "27001: A.5.34"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "PT-2",
+ "PT-2(2)",
+ "SA-4",
+ "SC-16",
+ "SC-16(3)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.DS-2"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.DS-02"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "1.2.1",
+ "1.2.5",
+ "1.2.6",
+ "2.2.4",
+ "2.2.5",
+ "2.2.7",
+ "4.2.1"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "s3_bucket_secure_transport_policy"
+ ]
+ },
+ {
+ "Id": "IVS-02",
+ "Description": "Plan and monitor the availability, quality, and adequate capacity of resources in order to deliver the required system performance as determined by the business.",
+ "Name": "Capacity and Resource Planning",
+ "Attributes": [
+ {
+ "Section": "Infrastructure & Virtualization Security",
+ "CCMLite": "No",
+ "IaaS": "CSP-Owned",
+ "PaaS": "CSP-Owned",
+ "SaaS": "CSP-Owned",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "A1.1"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "IVS-04"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "SY2.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: 5.3",
+ "27001: 6.1",
+ "27001: 9.1",
+ "27001: A.12.1.3",
+ "27002: 12.1.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: 5.3 (b)",
+ "27001: 6.1",
+ "27001: 9.1",
+ "27001: A.8.6",
+ "27001: A.8.14"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "CP-2",
+ "CP-2(2)",
+ "SC-5",
+ "SC-5(2)",
+ "SC-4",
+ "SI-4"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.DS-4",
+ "ID.BE-5"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.IR-04",
+ "GV.OC-04"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "autoscaling_group_multiple_az",
+ "autoscaling_group_multiple_instance_types"
+ ]
+ },
+ {
+ "Id": "IVS-03",
+ "Description": "Monitor, encrypt and restrict communications between environments to only authenticated and authorized connections, as justified by the business. Review these configurations at least annually, and support them by a documented justification of all allowed services, protocols, ports, and compensating controls.",
+ "Name": "Network Security",
+ "Attributes": [
+ {
+ "Section": "Infrastructure & Virtualization Security",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "CSP-Owned",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC6.1",
+ "CC6.7"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "IVS-06"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "3.8",
+ "3.1",
+ "12.2",
+ "13.6",
+ "13.9"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.1.2",
+ "5.2.7"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "NC1.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: 7.5",
+ "27001: 9.1",
+ "27001: A.13.1.1",
+ "27002: 13.1.1",
+ "27001: A.13.1.2",
+ "27002: 13.1.2",
+ "27001: A.13.1.3",
+ "27002: 13.1.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: 7.5",
+ "27001: 9.1",
+ "27001: A.5.15",
+ "27001: A.5.37",
+ "27001: A.8.5",
+ "27001: A.8.9",
+ "27001: A.8.16",
+ "27001: A.8.20",
+ "27001: A.8.21",
+ "27001: A.8.22",
+ "27001: A.8.24",
+ "27002: A.5.15 2nd c)",
+ "27002: 8.20",
+ "27002: 8.21",
+ "27002: 8.22",
+ "27002: 8.24"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "SC-1",
+ "SC-4",
+ "SC-7",
+ "SC-7(4)",
+ "SC-7(5)",
+ "SC-7(8)",
+ "SC-7(9)",
+ "SC-7(11)",
+ "SC-8",
+ "SC-8(1)",
+ "SC-11",
+ "SC-12",
+ "SC-16",
+ "SC-23",
+ "SC-29",
+ "SC-29(1)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.AC-5",
+ "PR.AC-7",
+ "PR.PT-4",
+ "DE.CM-1",
+ "DE.CM-7",
+ "PR.DS-2"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.IR-01",
+ "PR.AA-03",
+ "PR.AA-05",
+ "DE.CM-01",
+ "PR.DS-02",
+ "ID.AM-03"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "1.1.6",
+ "1.2",
+ "1.2.3",
+ "2.2",
+ "4.1.1",
+ "10.2"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "1.2.5",
+ "1.2.6",
+ "1.2.7",
+ "1.4.2",
+ "2.2.4",
+ "2.2.5",
+ "2.2.7",
+ "4.2.1",
+ "10.1.1"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "vpc_flow_logs_enabled",
+ "ec2_securitygroup_default_restrict_traffic",
+ "ec2_securitygroup_allow_ingress_from_internet_to_all_ports",
+ "ec2_securitygroup_allow_ingress_from_internet_to_any_port",
+ "ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22",
+ "ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389",
+ "ec2_securitygroup_allow_ingress_from_internet_to_high_risk_tcp_ports",
+ "ec2_networkacl_allow_ingress_any_port",
+ "ec2_networkacl_allow_ingress_tcp_port_22",
+ "ec2_networkacl_allow_ingress_tcp_port_3389",
+ "ec2_securitygroup_allow_wide_open_public_ipv4",
+ "vpc_peering_routing_tables_with_least_privilege",
+ "vpc_subnet_no_public_ip_by_default"
+ ]
+ },
+ {
+ "Id": "IVS-04",
+ "Description": "Harden host and guest OS, hypervisor or infrastructure control plane according to their respective best practices, and supported by technical controls, as part of a security baseline.",
+ "Name": "OS Hardening and Base Controls",
+ "Attributes": [
+ {
+ "Section": "Infrastructure & Virtualization Security",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "CSP-Owned",
+ "SaaS": "CSP-Owned",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC6.1",
+ "CC6.8",
+ "CC7.1"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "IVS-07",
+ "IVS-11"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "4.1",
+ "4.2"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "4.1.3",
+ "5.2.5"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "SY1.1",
+ "SY1.3",
+ "SY1.4"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: 7.5",
+ "27001: 9.1",
+ "27001: A.14.2.2",
+ "27002: 14.2.2",
+ "27001: A.14.2.3",
+ "27001 A.14.2.4",
+ "27018: 12.1.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: 7.5",
+ "27001: 9.1",
+ "27001: A.5.37",
+ "27001: A.8.5",
+ "27001: A.8.9",
+ "27001: A.8.16",
+ "27001: A.8.20",
+ "27001: A.8.22",
+ "27001: A.8.24",
+ "27002: 8.20",
+ "27002: 8.22",
+ "27002: 8.24"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "CM-6",
+ "CM-6(1)",
+ "SC-29",
+ "SC-29(1)",
+ "SC-2",
+ "SC-7",
+ "SC-7(12)",
+ "SC-30",
+ "SC-34",
+ "SC-35",
+ "SC-39",
+ "SC-44"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.IP-1",
+ "PR.PT-3"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.PS-01"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "2.2"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "2.2.1"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "ec2_instance_imdsv2_enabled",
+ "ec2_instance_account_imdsv2_enabled",
+ "ec2_launch_template_imdsv2_required",
+ "ec2_instance_managed_by_ssm",
+ "ssm_managed_compliant_patching"
+ ]
+ },
+ {
+ "Id": "IVS-06",
+ "Description": "Design, develop, deploy and configure applications and infrastructures such that CSP and CSC (tenant) user access and intra-tenant access is appropriately segmented and segregated, monitored and restricted from other tenants.",
+ "Name": "Segmentation and Segregation",
+ "Attributes": [
+ {
+ "Section": "Infrastructure & Virtualization Security",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "CSP-Owned",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "IVS-09"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "4.2.1",
+ "5.3.4",
+ "5.2.7"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "SC2.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: 9.1",
+ "27001: A.13.1.3",
+ "27002: 13.1.3",
+ "27017: 13.1.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: 9.1",
+ "27001: A.5.15",
+ "27001: A.5.20",
+ "27001: A.8.3",
+ "27001: A.8.9",
+ "27001: A.8.16",
+ "27001: A.8.22",
+ "27002: 5.15 (b)",
+ "27002: 8.3 (b)",
+ "27002: 8.16 (b)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "SC-3",
+ "SC-7",
+ "SC-7(20)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.AC-4",
+ "PR.AC-5"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.AA-05",
+ "PR.IR-01",
+ "PR.PS-01",
+ "PR.PS-06",
+ "DE.CM-09"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "2.6",
+ "8.3.1",
+ "10.8",
+ "11.3",
+ "A3.2.1",
+ "A3.3.1"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "A1.1.1",
+ "A1.1.2",
+ "A1.1.3"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "ec2_securitygroup_default_restrict_traffic",
+ "vpc_subnet_separate_private_public",
+ "vpc_peering_routing_tables_with_least_privilege",
+ "ec2_instance_public_ip",
+ "awslambda_function_inside_vpc",
+ "sagemaker_notebook_instance_vpc_settings_configured",
+ "sagemaker_models_vpc_settings_configured",
+ "sagemaker_training_jobs_vpc_settings_configured"
+ ]
+ },
+ {
+ "Id": "IVS-07",
+ "Description": "Use secure and encrypted communication channels when migrating servers, services, applications, or data to cloud environments. Such channels must include only up-to-date and approved protocols.",
+ "Name": "Migration to Cloud Environments",
+ "Attributes": [
+ {
+ "Section": "Infrastructure & Virtualization Security",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC6.1",
+ "CC6.7"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "IVS-10"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.1.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "IM1.4",
+ "IM1.4",
+ "NC1.4",
+ "SC2.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.13.1.1",
+ "27002: 13.1.1",
+ "27017: 13.1.1",
+ "27018: 13.1.1",
+ "27001: A.13.1.2",
+ "27002: 13.1.2",
+ "27017: 13.1.2",
+ "27018: 13.1.2",
+ "27001: A.13.1.3",
+ "27002: 13.1.3",
+ "27017: 13.1.3",
+ "27018: 13.1.3",
+ "27001: A.13.2.1",
+ "27002: 13.2.1",
+ "27017: 13.2.1",
+ "27018: 13.2.1",
+ "27001: A.13.2.2",
+ "27002: 13.2.2",
+ "27017: 13.2.2",
+ "27018: 13.2.2",
+ "27001: A.13.2.3",
+ "27002: 13.2.3",
+ "27017: 13.2.3",
+ "27018: 13.2.3",
+ "27001: A.13.2.4",
+ "27002: 13.2.4",
+ "27017: 13.2.4",
+ "27018: 13.2.4"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.14",
+ "27001: A.8.20",
+ "27001: A.8.24",
+ "27002: 8.20 (e)",
+ "27002: 8.24 Guidance (b,f), other information (a)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "AC-17",
+ "AC-20",
+ "SC-7",
+ "SC-7(28)",
+ "SC-8",
+ "SC-8(1)",
+ "SC-12",
+ "SC-23",
+ "SC-29",
+ "SI-7",
+ "SI-7(1)-(3)",
+ "SI-7(5)-(10)",
+ "SI-7(12)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.DS-2",
+ "PR.PT-4"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.DS-02"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "4.2.1"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "dms_endpoint_ssl_enabled"
+ ]
+ },
+ {
+ "Id": "IVS-09",
+ "Description": "Define, implement and evaluate processes, procedures and defense-in-depth techniques for protection, detection, and timely response to network-based attacks.",
+ "Name": "Network Defense",
+ "Attributes": [
+ {
+ "Section": "Infrastructure & Virtualization Security",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "CSP-Owned",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC6.6",
+ "CC6.8",
+ "CC7.1",
+ "CC7.2",
+ "CC7.5"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "IVS-13"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "13.3",
+ "13.8"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.2.3",
+ "5.2.4",
+ "5.2.5",
+ "5.2.7",
+ "5.3.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "NC1.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: 6.1",
+ "27001: 6.2",
+ "27001: A.14.1.2",
+ "27002: 14.1.2",
+ "27017: 14.1.2",
+ "27001: A.11.1.4",
+ "27002: 11.1.4",
+ "27017: 11.1.4",
+ "27018: 16.1.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: 6.1",
+ "27001: 6.2",
+ "27001: A.5.24",
+ "27001: A.5.26",
+ "27001: A.8.8",
+ "27001: A.8.16",
+ "27001: A.8.20",
+ "27001: A.8.21",
+ "27001: A.8.22",
+ "27001: A.8.26",
+ "27002: 8.8 (i)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "PL-8",
+ "PL-8(1)",
+ "SC-5",
+ "SC-5(1)",
+ "SC-5(3)",
+ "SC-7",
+ "SC-7(13)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "DE.AE-1",
+ "DE.DP-1",
+ "DE.CM-1",
+ "DE.CM-7",
+ "PR.AC-5",
+ "RS.MI-2",
+ "PR.DS-2",
+ "RS.RP-1"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "ID.AM-03",
+ "DE.CM-01",
+ "PR.IR-01",
+ "RS.MA-01",
+ "RS.MI-01",
+ "RS.MI-02"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "6.6",
+ "1.1",
+ "1.2",
+ "1.3",
+ "1.5",
+ "12.10.5"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "1.1.1",
+ "1.3.1",
+ "1.3.2",
+ "1.3.3",
+ "1.4.1",
+ "1.4.2",
+ "1.4.3",
+ "1.4.4",
+ "1.4.5",
+ "1.5.1",
+ "12.10.1"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "networkfirewall_in_all_vpc",
+ "networkfirewall_logging_enabled",
+ "networkfirewall_policy_rule_group_associated",
+ "wafv2_webacl_with_rules",
+ "wafv2_webacl_logging_enabled",
+ "elbv2_waf_acl_attached",
+ "cloudfront_distributions_using_waf",
+ "guardduty_is_enabled",
+ "shield_advanced_protection_in_cloudfront_distributions",
+ "shield_advanced_protection_in_internet_facing_load_balancers"
+ ]
+ },
+ {
+ "Id": "LOG-02",
+ "Description": "Define, implement and evaluate processes, procedures and technical measures to ensure the security and retention of audit logs.",
+ "Name": "Audit Logs Protection",
+ "Attributes": [
+ {
+ "Section": "Logging and Monitoring",
+ "CCMLite": "No",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "IVS-01"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "8.1",
+ "8.9",
+ "8.1"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "3.1.3",
+ "5.1.2",
+ "5.2.4"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "TM1.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.18.1.3",
+ "27002: 18.1.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.28",
+ "27001: A.5.33",
+ "27001: A.8.15"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "AU-4",
+ "AU-11"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.AC-4",
+ "PR.IP-4",
+ "PR.IP-6",
+ "PR.PT-1",
+ "PR.DS-1"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.AA-05",
+ "PR.DS-01",
+ "PR.DS-02",
+ "ID.AM-08",
+ "PR.DS-11",
+ "PR.PS-04"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "10.5",
+ "10.7"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "10.3.1",
+ "10.3.2",
+ "10.3.3",
+ "10.3.4",
+ "10.5.1"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "cloudtrail_log_file_validation_enabled",
+ "cloudtrail_kms_encryption_enabled",
+ "cloudtrail_logs_s3_bucket_is_not_publicly_accessible",
+ "cloudtrail_logs_s3_bucket_access_logging_enabled",
+ "cloudtrail_bucket_requires_mfa_delete",
+ "cloudwatch_log_group_kms_encryption_enabled",
+ "cloudwatch_log_group_not_publicly_accessible",
+ "s3_bucket_object_lock"
+ ]
+ },
+ {
+ "Id": "LOG-03",
+ "Description": "Identify and monitor security-related events within applications and the underlying infrastructure. Define and implement a system to generate alerts to responsible stakeholders based on such events and corresponding metrics.",
+ "Name": "Security Monitoring and Alerting",
+ "Attributes": [
+ {
+ "Section": "Logging and Monitoring",
+ "CCMLite": "No",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC6.8",
+ "CC7.3"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "SEF-03",
+ "SEF-05"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "8.5"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.2.4",
+ "5.2.7",
+ "1.6.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "TM1.2",
+ "TM1.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.12.4.1",
+ "27002: 12.4.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.28",
+ "27001: A.8.15"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "AU-5",
+ "AU-5(2)",
+ "AU-13"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "DE.AE-1",
+ "DE.AE-2",
+ "DE.AE-3",
+ "DE.AE-5",
+ "DE.CM-1",
+ "DE.CM-2",
+ "DE.CM-3",
+ "DE.CM-4",
+ "DE.CM-5",
+ "DE.CM-6",
+ "DE.CM-7",
+ "DE.DP-1",
+ "DE.DP-4",
+ "DE.AE-4"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.PS-04",
+ "DE.AE-02",
+ "DE.AE-03",
+ "DE.AE-04",
+ "DE.AE-06",
+ "DE.AE-07",
+ "DE.AE-08",
+ "DE.CM-01",
+ "DE.CM-02",
+ "DE.CM-03",
+ "DE.CM-06",
+ "DE.CM-09"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "10.2"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "10.2.1",
+ "10.2.2",
+ "10.4.1.1",
+ "10.4.2.1",
+ "10.4.3"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "guardduty_is_enabled",
+ "securityhub_enabled",
+ "cloudwatch_alarm_actions_enabled",
+ "cloudwatch_alarm_actions_alarm_state_configured",
+ "cloudwatch_log_metric_filter_unauthorized_api_calls",
+ "cloudwatch_log_metric_filter_root_usage",
+ "cloudwatch_log_metric_filter_sign_in_without_mfa"
+ ]
+ },
+ {
+ "Id": "LOG-04",
+ "Description": "Restrict audit logs access to authorized personnel and maintain records that provide unique access accountability.",
+ "Name": "Audit Logs Access and Accountability",
+ "Attributes": [
+ {
+ "Section": "Logging and Monitoring",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "IVS-01"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "3.14"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "3.1.1",
+ "4.1.2",
+ "4.1.3",
+ "4.2.1",
+ "5.2.4"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "TM1.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.12.4.2",
+ "27001: A.12.4.1",
+ "27002: 12.4.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.33",
+ "27001: A.8.15"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "AU-9",
+ "AU-9(4)",
+ "AU-9(6)",
+ "AU-10"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.AC-1",
+ "PR.AC-4"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.AA-05",
+ "PR.PS-04"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "10.1",
+ "10.2.1",
+ "10.2.3",
+ "10.5.1",
+ "10.5.2"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "10.2.1.3",
+ "10.3.1"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "cloudtrail_logs_s3_bucket_is_not_publicly_accessible",
+ "cloudwatch_log_group_not_publicly_accessible"
+ ]
+ },
+ {
+ "Id": "LOG-05",
+ "Description": "Monitor security audit logs to detect activity outside of typical or expected patterns. Establish and follow a defined process to review and take appropriate and timely actions on detected anomalies.",
+ "Name": "Audit Logs Monitoring and Response",
+ "Attributes": [
+ {
+ "Section": "Logging and Monitoring",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC7.2"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "8.8",
+ "8.11"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "1.6.1",
+ "1.6.2",
+ "5.2.4"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "TM1.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.12.4.3",
+ "27002: 12.4.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.8.15",
+ "27001: A.8.16"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "AU-6",
+ "AU-6(1)",
+ "AU-6(5)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "DE.AE-3",
+ "PR.PT-1",
+ "RS.AN-1",
+ "RS.CO-1.",
+ "DE.AE-1",
+ "DE.AE-5",
+ "DE.DP-4"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "ID.AM-03",
+ "PR.PS-04",
+ "DE.AE-02",
+ "DE.AE-03",
+ "DE.AE-06",
+ "DE.AE-07",
+ "DE.AE-08",
+ "DE.CM-01",
+ "DE.CM-02",
+ "DE.CM-03",
+ "DE.CM-06",
+ "DE.CM-09"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "10.6",
+ "10.6.1"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "10.4.1.1",
+ "10.4.2.1"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "cloudwatch_log_metric_filter_unauthorized_api_calls",
+ "cloudwatch_log_metric_filter_root_usage",
+ "cloudwatch_log_metric_filter_sign_in_without_mfa",
+ "cloudwatch_log_metric_filter_policy_changes",
+ "cloudwatch_log_metric_filter_security_group_changes",
+ "cloudwatch_changes_to_network_acls_alarm_configured",
+ "cloudwatch_changes_to_network_gateways_alarm_configured",
+ "cloudwatch_changes_to_network_route_tables_alarm_configured",
+ "cloudwatch_changes_to_vpcs_alarm_configured",
+ "cloudwatch_log_metric_filter_authentication_failures",
+ "cloudwatch_log_metric_filter_disable_or_scheduled_deletion_of_kms_cmk",
+ "cloudwatch_log_metric_filter_for_s3_bucket_policy_changes",
+ "cloudwatch_log_metric_filter_aws_organizations_changes",
+ "guardduty_no_high_severity_findings"
+ ]
+ },
+ {
+ "Id": "LOG-07",
+ "Description": "Establish, document and implement which information meta/data system events should be logged. Review and update the scope at least annually or whenever there is a change in the threat environment.",
+ "Name": "Logging Scope",
+ "Attributes": [
+ {
+ "Section": "Logging and Monitoring",
+ "CCMLite": "No",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC7.2"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "8.1"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.2.4"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "TM1.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: 7.5.3",
+ "27001: A.12.4.1",
+ "27002: 12.4.1",
+ "27017: 12.4.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: 7.5.3",
+ "27001: A.8.15"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "AU-1",
+ "AU-14",
+ "AU-16"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "ID.SC-3",
+ "ID.SC-4",
+ "PR.PT-1",
+ "ID.GV-1"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.PS-04"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "10.3"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "10.2.1",
+ "10.2.2"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "cloudtrail_multi_region_enabled",
+ "cloudtrail_multi_region_enabled_logging_management_events",
+ "cloudtrail_s3_dataevents_read_enabled",
+ "cloudtrail_s3_dataevents_write_enabled",
+ "vpc_flow_logs_enabled",
+ "awslambda_function_invoke_api_operations_cloudtrail_logging_enabled"
+ ]
+ },
+ {
+ "Id": "LOG-08",
+ "Description": "Generate audit records containing relevant security information.",
+ "Name": "Log Records",
+ "Attributes": [
+ {
+ "Section": "Logging and Monitoring",
+ "CCMLite": "No",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC7.2"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "8.2"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.2.4"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "TM1.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.12.4.1",
+ "27002: 12.4.1",
+ "27017: 12.4.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.8.15"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "AU-3",
+ "AU-3(1)",
+ "AU-3(3)",
+ "AU-6",
+ "AU-6(8)",
+ "AU-12",
+ "AU-12(1)",
+ "AU-12(2)",
+ "AU-12(3)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.PT-1",
+ "DE.AE-3",
+ "DE.CM-1",
+ "DE.CM-2",
+ "DE.CM-3",
+ "DE.CM-6",
+ "DE.CM-7"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.PS-04",
+ "DE.CM-01",
+ "DE.CM-02",
+ "DE.CM-03",
+ "DE.CM-06",
+ "DE.CM-09"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "10.3"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "10.2.2"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "cloudtrail_multi_region_enabled",
+ "cloudtrail_cloudwatch_logging_enabled",
+ "vpc_flow_logs_enabled",
+ "s3_bucket_server_access_logging_enabled",
+ "elb_logging_enabled",
+ "elbv2_logging_enabled",
+ "cloudfront_distributions_logging_enabled",
+ "route53_public_hosted_zones_cloudwatch_logging_enabled",
+ "wafv2_webacl_logging_enabled",
+ "redshift_cluster_audit_logging",
+ "rds_cluster_integration_cloudwatch_logs",
+ "rds_instance_integration_cloudwatch_logs",
+ "opensearch_service_domains_audit_logging_enabled",
+ "eks_control_plane_logging_all_types_enabled",
+ "apigateway_restapi_logging_enabled",
+ "apigatewayv2_api_access_logging_enabled",
+ "networkfirewall_logging_enabled",
+ "mq_broker_logging_enabled",
+ "documentdb_cluster_cloudwatch_log_export",
+ "neptune_cluster_integration_cloudwatch_logs",
+ "codebuild_project_logging_enabled",
+ "glue_etl_jobs_logging_enabled",
+ "stepfunctions_statemachine_logging_enabled",
+ "datasync_task_logging_enabled",
+ "ec2_client_vpn_endpoint_connection_logging_enabled",
+ "elasticbeanstalk_environment_cloudwatch_logging_enabled"
+ ]
+ },
+ {
+ "Id": "LOG-09",
+ "Description": "The information system protects audit records from unauthorized access, modification, and deletion.",
+ "Name": "Log Protection",
+ "Attributes": [
+ {
+ "Section": "Logging and Monitoring",
+ "CCMLite": "No",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "GRM-04",
+ "IVS-01"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.2.4",
+ "4.2.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "TM1.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.12.4.2",
+ "27002: 12.4.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.8.15"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "AU-9",
+ "AU-9(2)",
+ "AU-9(3)",
+ "AU-9(4)",
+ "AU-12(3)",
+ "AU-12(3)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.AC-4",
+ "PR.IP-4",
+ "PR.IP-6",
+ "PR.PT-1",
+ "PR.DS-1",
+ "PR.DS-6"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.AA-05",
+ "PR.DS-01",
+ "PR.DS-02",
+ "PR.DS-11"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "10.5",
+ "10.5.1",
+ "10.5.2"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "10.3.1",
+ "10.3.2",
+ "10.3.3",
+ "10.3.4"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "cloudtrail_log_file_validation_enabled",
+ "cloudtrail_kms_encryption_enabled",
+ "cloudtrail_logs_s3_bucket_is_not_publicly_accessible",
+ "cloudwatch_log_group_kms_encryption_enabled",
+ "cloudwatch_log_group_not_publicly_accessible"
+ ]
+ },
+ {
+ "Id": "LOG-10",
+ "Description": "Establish and maintain a monitoring and internal reporting capability over the operations of cryptographic, encryption and key management policies, processes, procedures, and controls.",
+ "Name": "Encryption Monitoring and Reporting",
+ "Attributes": [
+ {
+ "Section": "Logging and Monitoring",
+ "CCMLite": "No",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC6.1",
+ "CC7.2"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "EKM-02",
+ "EKM-03"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "4.2.1",
+ "5.1.1",
+ "5.1.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "TS2.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.10.1",
+ "27002: 10.1",
+ "27001: A.10.1.2",
+ "27017: 10.1.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.8.24"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "AU-1",
+ "AU-9",
+ "AU-9(3)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "ID.GV-1",
+ "PR.PT-1"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.PS-04",
+ "DE.CM-09"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "10.1.1",
+ "10.2.1",
+ "10.4.1"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "kms_cmk_rotation_enabled",
+ "acm_certificates_expiration_check"
+ ]
+ },
+ {
+ "Id": "LOG-11",
+ "Description": "Log and monitor key lifecycle management events to enable auditing and reporting on usage of cryptographic keys.",
+ "Name": "Transaction/Activity Logging",
+ "Attributes": [
+ {
+ "Section": "Logging and Monitoring",
+ "CCMLite": "No",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC6.1",
+ "CC7.2"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "EKM-02"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.1.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "TS2.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.10.1.2",
+ "27017: 10.1.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.8.24"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "AU-9",
+ "AU-9(3)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.PT-1",
+ "DE.AE-3"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.PS-04",
+ "DE.CM-09"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "cloudtrail_s3_dataevents_read_enabled",
+ "cloudtrail_s3_dataevents_write_enabled",
+ "cloudtrail_multi_region_enabled_logging_management_events"
+ ]
+ },
+ {
+ "Id": "LOG-13",
+ "Description": "Define, implement and evaluate processes, procedures and technical measures for the reporting of anomalies and failures of the monitoring system and provide immediate notification to the accountable party.",
+ "Name": "Failures and Anomalies Reporting",
+ "Attributes": [
+ {
+ "Section": "Logging and Monitoring",
+ "CCMLite": "No",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC2.3",
+ "CC7.3"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "SEF-03"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "1.6.1",
+ "5.2.4"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "TM1.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.16.1.1",
+ "27002: 16.1.1",
+ "27001: A.16.1.2",
+ "27017: 16.1.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.24",
+ "27001: A.6.8",
+ "27002: 6.8 (g)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "AU-5",
+ "AU-5(2)",
+ "AU-6",
+ "AU-6(3)",
+ "AU-6(4)",
+ "AU-6(5)",
+ "AU-16"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "DE.DP-3",
+ "DE.DP-4"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.PS-04",
+ "DE.AE-06"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "10.6"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "10.4.3",
+ "10.7.1",
+ "10.7.2",
+ "10.7.3"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "guardduty_is_enabled",
+ "guardduty_no_high_severity_findings",
+ "cloudwatch_alarm_actions_enabled",
+ "cloudwatch_alarm_actions_alarm_state_configured"
+ ]
+ },
+ {
+ "Id": "SEF-03",
+ "Description": "'Establish, document, approve, communicate, apply, evaluate and maintain a security incident response plan, which includes but is not limited to: relevant internal departments, impacted CSCs, and other business critical relationships (such as supply-chain) that may be impacted.'",
+ "Name": "Incident Response Plans",
+ "Attributes": [
+ {
+ "Section": "Security Incident Management, E-Discovery, & Cloud Forensics",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC7.2",
+ "CC7.3",
+ "CC7.4"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "BCR-02"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "17.2",
+ "17.4"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "1.6.2",
+ "1.6.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "TM2.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: 5.2",
+ "27001: 7.3",
+ "27001: 7.4",
+ "27001: 7.5",
+ "27001: A.16.1.5",
+ "27002: 16.1.5",
+ "27017: 16.1.5",
+ "27017: CLD.12.1.5",
+ "27018: 16.1.5"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: 5.2",
+ "27001: 7.3",
+ "27001: 7.4",
+ "27001: 7.5",
+ "27001: A.5.26",
+ "27002: 5.26 (e,f)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "IR-1",
+ "IR-2",
+ "IR-2(1)-(3)",
+ "IR-3",
+ "IR-3(1)-(3)",
+ "IR-4",
+ "IR-4(1)-(15)",
+ "IR-5",
+ "IR-5(1)",
+ "IR-6",
+ "IR-6(1)-(3)",
+ "IR-7",
+ "IR-7(1)",
+ "IR-7(2)",
+ "IR-8",
+ "IR-8(1)",
+ "IR-9",
+ "IR-9(1)-(4)",
+ "PM-12"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "RS.CO-1",
+ "RS.CO-4",
+ "ID.AM-6",
+ "ID.GV-2",
+ "ID.SC-5",
+ "PR.IP-9",
+ "PR.IP10"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.AT-01",
+ "PR.AT-02",
+ "RS.MA-01",
+ "GV.SC-08",
+ "ID.IM-02",
+ "ID.IM-04",
+ "RC.RP-01"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "12.1",
+ "12.10.1"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "12.10.1",
+ "12.10.5"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "ssmincidents_enabled_with_plans"
+ ]
+ },
+ {
+ "Id": "SEF-06",
+ "Description": "Define, implement and evaluate processes, procedures and technical measures supporting business processes to triage security-related events.",
+ "Name": "Event Triage Processes",
+ "Attributes": [
+ {
+ "Section": "Security Incident Management, E-Discovery, & Cloud Forensics",
+ "CCMLite": "No",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC7.3"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "SEF-02"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "1.6.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "TM1.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.16.1.4",
+ "27002: 16.1.4",
+ "27017: 16.1.4",
+ "27018: 16.1.4",
+ "27001: A.16.1.5",
+ "27002: 16.1.5",
+ "27017: 16.1.5",
+ "27018: 16.1.5"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.25"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "CA-7",
+ "CA-7(3)",
+ "CA-7(4)",
+ "CA-7(5)",
+ "CA-7(6)",
+ "IR-4",
+ "IR-4(1)",
+ "IR-4(3)",
+ "IR-4(4)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "DE.AE-1",
+ "DE.AE-2",
+ "DE.AE-4",
+ "RS.RP-1",
+ "RS.AN-2"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "RS.MA-02",
+ "RS.MA-03",
+ "RS.AN-03",
+ "DE.AE-02",
+ "DE.AE-04",
+ "DE.AE-06",
+ "DE.AE-07",
+ "DE.AE-08",
+ "RS.MI-02",
+ "RC.RP-02"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "12.5.2"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "12.10.1"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "guardduty_is_enabled",
+ "securityhub_enabled"
+ ]
+ },
+ {
+ "Id": "SEF-08",
+ "Description": "Maintain points of contact for applicable regulation authorities, national and local law enforcement, and other legal jurisdictional authorities.",
+ "Name": "Points of Contact Maintenance",
+ "Attributes": [
+ {
+ "Section": "Security Incident Management, E-Discovery, & Cloud Forensics",
+ "CCMLite": "No",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC2.3"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "SEF-01"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "17.2"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "1.6.2",
+ "1.6.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "SM2.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: 4.2",
+ "27001: A.6.1.3",
+ "27002: 6.1.3",
+ "27017: 6.1.3",
+ "27018: 6.1.3",
+ "27001: A.16.1.1",
+ "27002: 16.1.1",
+ "27001: A.18.1.1",
+ "27002: 18.1.1",
+ "27017: 18.1.1",
+ "27018: 18.1.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.5",
+ "27001: A.5.24",
+ "27002: 5.24 Incident management procedure (d)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "IR-4",
+ "IR-4(8)",
+ "IR-6",
+ "IR-6(3)",
+ "IR-7",
+ "IR-7(2)",
+ "PM-21",
+ "PM-23",
+ "PM-26"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "ID.GV-2",
+ "RS.CO-3",
+ "RS.CO-4"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "GV.RR-02",
+ "RS.CO-02",
+ "RS.CO-03"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "12.10.1"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "account_maintain_current_contact_details",
+ "account_security_contact_information_is_registered",
+ "account_maintain_different_contact_details_to_security_billing_and_operations"
+ ]
+ },
+ {
+ "Id": "TVM-02",
+ "Description": "Establish, document, approve, communicate, apply, evaluate and maintain policies and procedures to protect against malware on managed assets. Review and update the policies and procedures at least annually.",
+ "Name": "Malware Protection Policy and Procedures",
+ "Attributes": [
+ {
+ "Section": "Threat & Vulnerability Management",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC5.3",
+ "CC6.8"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "TVM-01",
+ "GRM-06",
+ "GRM-09"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "9.7",
+ "10.1"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "1.1.1",
+ "1.5.1",
+ "5.2.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "TS1.2",
+ "TS1.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: 5.1",
+ "27001: 5.2",
+ "27001: 7.3",
+ "27001: 7.4",
+ "27001: 7.5",
+ "27001: 9.1",
+ "27001: 9.3",
+ "27001: A.5",
+ "27002: 5",
+ "27001: A.12.2.1",
+ "27001: A.6.2.1",
+ "27002: 6.2.1 (h)",
+ "27001: A.6.2.2",
+ "27002: 6.2.2 (j)",
+ "27001: A.7.2.2",
+ "27002: 7.2.2 (d)",
+ "27001: A.10.1.1",
+ "27002: 10.1.1 (g)",
+ "27001: A.13.2.1",
+ "27002: 13.2.1 (b)",
+ "27001: A.15.1.2",
+ "27017: 15.1.2",
+ "27001: A.12.2.1",
+ "27002: 12.2.1 (a),(d)",
+ "27017: CLD.9.5.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: 5.1",
+ "27001: 5.2",
+ "27001: 7.3",
+ "27001: 7.4",
+ "27001: 7.5",
+ "27001: 9.1",
+ "27001: 9.3",
+ "27001: A.5.1",
+ "27001: A.5.4",
+ "27001: A.5.7",
+ "27001: A.5.37",
+ "27001: A.8.7",
+ "27002: 5.7 (b)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "RA-3",
+ "RA-3(3)",
+ "RA-5",
+ "RA-5(3)",
+ "RA-5(5)",
+ "SI-3",
+ "SI-3(4)",
+ "SI-3(10)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "ID.GV-1",
+ "DE.CM-4",
+ "DE.CM-5"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "GV.PO-01",
+ "GV.PO-02",
+ "ID.IM-03",
+ "DE.CM-01",
+ "DE.CM-09"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "5.4",
+ "12.1",
+ "12.1.1",
+ "12.3.1",
+ "12.5.1",
+ "12.11"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "12.1.1",
+ "12.1.2",
+ "5.1.1",
+ "5.3.2.1"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "guardduty_ec2_malware_protection_enabled"
+ ]
+ },
+ {
+ "Id": "TVM-03",
+ "Description": "Define, implement and evaluate processes, procedures and technical measures to enable both scheduled and emergency responses to vulnerability identifications, based on the identified risk.",
+ "Name": "Vulnerability Remediation Schedule",
+ "Attributes": [
+ {
+ "Section": "Threat & Vulnerability Management",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC5.3",
+ "CC7.1",
+ "CC7.4"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "TVM-02"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "7.2",
+ "7.7",
+ "17.9"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.2.5"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "TM1.1",
+ "TM2.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: 6.1.3",
+ "27001: A.12.2.1",
+ "27001: A.12.6.1",
+ "27002: 12.6.1(c)(d)(j)",
+ "27018: 12.6.1(k)(i)"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: 6.1.3",
+ "27001: A.8.7",
+ "27001: A.8.8",
+ "27001: A.8.32",
+ "27002: 8.7",
+ "27002: 8.8",
+ "27002: 8.32"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "PM-31",
+ "RA-3",
+ "RA-3(1)",
+ "RA-5",
+ "RA-5(2)-(4)",
+ "RA-5(6)",
+ "SI-3",
+ "SI-3(10)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "RS.AN-5",
+ "PR.IP-12"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "ID.RA-01",
+ "ID.RA-06",
+ "ID.RA-08",
+ "PR.PS-02",
+ "PR.PS-03"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "6.1",
+ "6.1.a",
+ "6.1.b"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "6.1.1",
+ "6.3.1",
+ "6.3.2",
+ "6.3.3",
+ "12.10.1"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "ssm_managed_compliant_patching",
+ "rds_instance_minor_version_upgrade_enabled",
+ "rds_cluster_minor_version_upgrade_enabled",
+ "redshift_cluster_automatic_upgrades",
+ "elasticbeanstalk_environment_managed_updates_enabled",
+ "dms_instance_minor_version_upgrade_enabled",
+ "elasticache_redis_cluster_auto_minor_version_upgrades",
+ "memorydb_cluster_auto_minor_version_upgrades",
+ "mq_broker_auto_minor_version_upgrades",
+ "opensearch_service_domains_updated_to_the_latest_service_software_version",
+ "kafka_cluster_uses_latest_version"
+ ]
+ },
+ {
+ "Id": "TVM-04",
+ "Description": "Define, implement and evaluate processes, procedures and technical measures to update detection tools, threat signatures, and indicators of compromise on a weekly, or more frequent basis.",
+ "Name": "Detection Updates",
+ "Attributes": [
+ {
+ "Section": "Threat & Vulnerability Management",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC7.2"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "No mapping"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "10.2"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.2.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "TS1.3",
+ "TS1.4",
+ "TM1.3",
+ "TM1.4",
+ "IM1.5"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: 6.1.3",
+ "27001: A.5.1.1",
+ "27002: 5.1.1 (h)",
+ "27001: A.12.6.1",
+ "27002: 12.6.1 (b),(c)"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: 6.1.3",
+ "27001: A.5.1",
+ "27001: A.8.8",
+ "27001: A.8.15",
+ "27001: A.8.16",
+ "27002: 5.1",
+ "27002: 5.37",
+ "27002: 8.8",
+ "27002: 8.15 (d)",
+ "27002: 8.16 (d,e)",
+ "27002: 8.31 2nd (a)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "CM-7",
+ "CM-7(4)",
+ "RA-3",
+ "RA-3(3)",
+ "RA-5(2)",
+ "SA-10",
+ "SA-10(5)",
+ "SA-11",
+ "SA-11(2)",
+ "SI-2",
+ "SI-2(4)",
+ "SI-3",
+ "SI-3(4)",
+ "SI-4",
+ "SI-4(9)",
+ "SI-4(24)",
+ "SI-8",
+ "SI-8(2)",
+ "SI-8(3)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "DE.DP-5",
+ "PR.IP-12"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.PS-02",
+ "ID.RA-02"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "5.2",
+ "5.2a",
+ "5.2b",
+ "5.2c"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "5.3.1"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "guardduty_is_enabled",
+ "inspector2_is_enabled"
+ ]
+ },
+ {
+ "Id": "TVM-05",
+ "Description": "Define, implement and evaluate processes, procedures and technical measures to identify updates for applications which use third party or open source libraries according to the organization's vulnerability management policy.",
+ "Name": "External Library Vulnerabilities",
+ "Attributes": [
+ {
+ "Section": "Threat & Vulnerability Management",
+ "CCMLite": "No",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "CSP-Owned",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC3.2"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "No mapping"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "2.6"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "TM1.1",
+ "SD2.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: 6.1.3",
+ "27001: A.12.6.2",
+ "27002: 12.6.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: 6.1.3",
+ "27001: A 5.6",
+ "27001: A.8.19",
+ "27001: A.8.8",
+ "27001: A.8.28",
+ "27001: A.8.31",
+ "27002: 5.6 (c)",
+ "27001: 8.19",
+ "27001: 8.8",
+ "27001: 8.28",
+ "27001: 8.31"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "RA-5",
+ "RA-5(3)",
+ "SA-11",
+ "SA-11(2)",
+ "SA-11(5)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "DE.DP-5",
+ "PR.IP-12"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "ID.RA-01",
+ "ID.RA-03",
+ "PR.PS-02"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "6.1",
+ "6.2",
+ "6.3.2"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "6.3.1",
+ "6.3.2",
+ "6.3.3"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "inspector2_is_enabled",
+ "ecr_repositories_scan_vulnerabilities_in_latest_image",
+ "ecr_registry_scan_images_on_push_enabled"
+ ]
+ },
+ {
+ "Id": "TVM-07",
+ "Description": "Define, implement and evaluate processes, procedures and technical measures for the detection of vulnerabilities on organizationally managed assets at least monthly.",
+ "Name": "Vulnerability Identification",
+ "Attributes": [
+ {
+ "Section": "Threat & Vulnerability Management",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC7.1"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "TVM-02"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "7.1",
+ "7.5",
+ "7.6"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.2.5",
+ "5.2.6"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "TM1.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.12.6",
+ "27001: A.12.6.1",
+ "27002: 12.6.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.8.8",
+ "27002: 8.8"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "RA-5",
+ "RA-5(4)",
+ "RA-5(5)",
+ "SA-11",
+ "SA-11(5)",
+ "SA-15(5)",
+ "SC-7",
+ "SC-7(10)",
+ "SI-3(8)",
+ "SI-3(10)",
+ "SI-7",
+ "SI-7(9)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "ID.RA-1",
+ "DE.CM-8",
+ "PR.IP-12"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "ID.RA-01"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "6.1",
+ "11.2",
+ "11.2.1"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "6.3.1",
+ "6.3.2",
+ "6.3.3",
+ "11.3.2",
+ "11.3.2.1"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "inspector2_is_enabled",
+ "inspector2_active_findings_exist",
+ "guardduty_is_enabled",
+ "ecr_repositories_scan_vulnerabilities_in_latest_image"
+ ]
+ },
+ {
+ "Id": "UEM-08",
+ "Description": "Protect information from unauthorized disclosure on managed endpoint devices with storage encryption.",
+ "Name": "Storage Encryption",
+ "Attributes": [
+ {
+ "Section": "Universal Endpoint Management",
+ "CCMLite": "No",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC6.1",
+ "CC6.7"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "MOS-11"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "3.6"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.1.2",
+ "3.1.4"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "PA1.2",
+ "PA1.3",
+ "PA1.5",
+ "PA2.2",
+ "PM1.4"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.11.2.7",
+ "27002: 11.2.7",
+ "27001: A.18.1.1",
+ "27017: 18.1.1",
+ "27001: A.12.3.1",
+ "27017: 12.3.1",
+ "27018: A.11.4",
+ "27018: A.11.5"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.8.1",
+ "27002: 8.1 (h)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "AC-19(5)",
+ "SC-28",
+ "SC-28(1)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.DS-1"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.DS-01"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "3.4",
+ "3.6"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "3.5.1",
+ "3.6"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "ec2_ebs_volume_encryption",
+ "ec2_ebs_default_encryption",
+ "workspaces_volume_encryption_enabled"
+ ]
+ },
+ {
+ "Id": "UEM-11",
+ "Description": "Configure managed endpoints with Data Loss Prevention (DLP) technologies and rules in accordance with a risk assessment.",
+ "Name": "Data Loss Prevention",
+ "Attributes": [
+ {
+ "Section": "Universal Endpoint Management",
+ "CCMLite": "No",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC6.7"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "3.13"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.2.7"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "IM1.5",
+ "PA2.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.12.3",
+ "27002: 12.3",
+ "27001: A.8.3.1",
+ "27002: 8.3.1",
+ "27001: A.12.2",
+ "27002: 12.2",
+ "27001: A.18.1.3",
+ "27002: 18.1.3",
+ "27001: A.6.1.1",
+ "27017: 6.1.1",
+ "27018: 12.3.1",
+ "27018: 10.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.12",
+ "27001: A.8.3"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "SC-7",
+ "SC-7(10)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.DS-5"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.DS-02",
+ "PR.DS-10",
+ "PR.PS-01",
+ "ID.AM-08",
+ "DE.CM-09"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "A3.2.6"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "A3.2.6"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "macie_is_enabled",
+ "macie_automated_sensitive_data_discovery_enabled"
+ ]
+ }
+ ]
+}
diff --git a/prowler/compliance/azure/csa_ccm_4.0_azure.json b/prowler/compliance/azure/csa_ccm_4.0_azure.json
new file mode 100644
index 0000000000..b4505ac089
--- /dev/null
+++ b/prowler/compliance/azure/csa_ccm_4.0_azure.json
@@ -0,0 +1,7548 @@
+{
+ "Framework": "CSA-CCM",
+ "Name": "CSA Cloud Controls Matrix (CCM) v4.0.13",
+ "Version": "4.0",
+ "Provider": "Azure",
+ "Description": "The Cloud Security Alliance (CSA) Cloud Controls Matrix (CCM) is a cybersecurity control framework for cloud computing, composed of 197 control objectives structured in 17 domains covering all key aspects of cloud technology. The CCM can be used as a tool for the systematic assessment of a cloud implementation, and provides guidance on which security controls should be implemented by which actor within the cloud supply chain.",
+ "Requirements": [
+ {
+ "Id": "A&A-02",
+ "Description": "Conduct independent audit and assurance assessments according to relevant standards at least annually.",
+ "Name": "Independent Assessments",
+ "Attributes": [
+ {
+ "Section": "Audit & Assurance",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC4.1"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "AAC-02"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "1.5.2",
+ "5.2.6"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "AS1.1",
+ "AS2.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.18.2.1",
+ "27002: 18.2.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.35",
+ "27001: A.5.36"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "CA-2",
+ "CA-2(1)",
+ "CA-2(2)",
+ "CA-7",
+ "CA-7(1)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "ID.IM-01"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "defender_ensure_defender_for_app_services_is_on",
+ "defender_ensure_defender_for_azure_sql_databases_is_on",
+ "defender_ensure_defender_for_databases_is_on",
+ "defender_ensure_defender_for_keyvault_is_on",
+ "defender_ensure_defender_for_server_is_on"
+ ]
+ },
+ {
+ "Id": "A&A-04",
+ "Description": "Verify compliance with all relevant standards, regulations, legal/contractual, and statutory requirements applicable to the audit.",
+ "Name": "Requirements Compliance",
+ "Attributes": [
+ {
+ "Section": "Audit & Assurance",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC3.1"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "GRM-01",
+ "GRM-03"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "7.1.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "AS1.1",
+ "AS2.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: 9.3.2",
+ "27001: A.18.2.2",
+ "27002: 18.2.2",
+ "27001: A.18.2.3",
+ "27002: 18.2.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: 9.3.2",
+ "27001: A.5.31",
+ "27001: A.5.32",
+ "27001: A.5.33",
+ "27001: A.5.34",
+ "27001: A.5.36"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "CA-1"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "ID.GV-3",
+ "DE.DP-2"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "ID.IM-01"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "defender_ensure_defender_for_app_services_is_on",
+ "defender_ensure_defender_for_azure_sql_databases_is_on",
+ "defender_ensure_defender_for_databases_is_on",
+ "defender_ensure_defender_for_server_is_on",
+ "defender_ensure_mcas_is_enabled",
+ "monitor_diagnostic_settings_exists",
+ "policy_ensure_asc_enforcement_enabled"
+ ]
+ },
+ {
+ "Id": "AIS-04",
+ "Description": "Define and implement a SDLC process for application design, development, deployment, and operation in accordance with security requirements defined by the organization.",
+ "Name": "Secure Application Design and Development",
+ "Attributes": [
+ {
+ "Section": "Application & Interface Security",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "CSP-Owned",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC6.8",
+ "CC8.1"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "AIS-01",
+ "AIS-03"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "16.1"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "1.3.4",
+ "5.3.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "SD1.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.14.1.1",
+ "27002: 14.1.1",
+ "27017: 14.1.1",
+ "27001: A.14.1.2",
+ "27002: 14.1.2",
+ "27017: 14.1.2",
+ "27001: A.14.2.1",
+ "27002: 14.2.1",
+ "27017: 14.2.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.8",
+ "27001: A.8.25",
+ "27001: A.8.26",
+ "27001: A.8.28"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "PL-2",
+ "PL-8",
+ "PL-8(1)",
+ "SA-3",
+ "SA-3(1)",
+ "SA-4",
+ "SA-4(2)",
+ "SA-4(3)",
+ "SA-4(8)",
+ "SA-4(9)",
+ "SA-5",
+ "SA-8",
+ "SA-8(1)-(7)",
+ "SA-8(9)-(13)",
+ "SA-8(15)-(20)",
+ "SA-8(22)",
+ "SA-8(24)-(28)",
+ "SA-8(30)-(33)",
+ "SA-17",
+ "SA-17(1)-(9)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.DS-6",
+ "PR.DS-7",
+ "PR.IP-2"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "ID.AM-08",
+ "PR.IR-01",
+ "PR.PS-01",
+ "PR.PS-02",
+ "PR.PS-06"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "6.3"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "6.2.1",
+ "6.2.3",
+ "6.5.2"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "app_ensure_auth_is_set_up",
+ "app_ftp_deployment_disabled",
+ "app_function_access_keys_configured",
+ "app_function_ftps_deployment_disabled",
+ "app_register_with_identity"
+ ]
+ },
+ {
+ "Id": "AIS-05",
+ "Description": "Implement a testing strategy, including criteria for acceptance of new information systems, upgrades and new versions, which provides application security assurance and maintains compliance while enabling organizational speed of delivery goals. Automate when applicable and possible.",
+ "Name": "Automated Application Security Testing",
+ "Attributes": [
+ {
+ "Section": "Application & Interface Security",
+ "CCMLite": "No",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC6.8",
+ "CC8.1"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "AIS-01",
+ "AIS-03"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "16.12",
+ "16.13"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "SD2.3",
+ "SD2.5"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.14.2.8",
+ "27001: A.14.2.9",
+ "27001: A.12.1.2",
+ "27002: 12.1.2",
+ "27001: A.14.1.1",
+ "27002: 14.1.1",
+ "27001: A.14.2.2",
+ "27002: 14.2.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.8.25",
+ "27001: A.8.29",
+ "27001: A.8.32",
+ "27002: 8.25 (e)",
+ "27002: 8.32 (d)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "SA-11",
+ "SA-11(1)-(9)",
+ "SI-6",
+ "SI-6(2)",
+ "SI-6(3)",
+ "SI-10",
+ "SI-10(1)-(6)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.IP-2",
+ "PR.PT-3",
+ "PR.IP-12",
+ "DE.CM-8"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "ID.AM-08",
+ "ID.RA-01",
+ "PR.PS-01",
+ "PR.PS-02"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "A.3.2.2",
+ "A.3.2.2.1",
+ "6.6"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "6.2.4",
+ "6.4.1",
+ "6.4.2",
+ "6.5.1"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "defender_auto_provisioning_vulnerabilty_assessments_machines_on",
+ "defender_container_images_resolved_vulnerabilities",
+ "defender_container_images_scan_enabled",
+ "defender_ensure_defender_for_containers_is_on",
+ "sqlserver_va_periodic_recurring_scans_enabled",
+ "sqlserver_vulnerability_assessment_enabled"
+ ]
+ },
+ {
+ "Id": "AIS-07",
+ "Description": "Define and implement a process to remediate application security vulnerabilities, automating remediation when possible.",
+ "Name": "Application Vulnerability Remediation",
+ "Attributes": [
+ {
+ "Section": "Application & Interface Security",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC7.1",
+ "CC7.4",
+ "CC8.1"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "TVM-02"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "16.2",
+ "16.6"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "TM1.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.16.1.5",
+ "27002: 16.1.5",
+ "27017: 16.1.5",
+ "27001: A.12.6.1",
+ "27002: 12.6.1",
+ "27017: 12.6.1",
+ "27018: 12.6.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.26",
+ "27001: A.8.8",
+ "27002: 5.26 (j)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "SI-2",
+ "SI-2(2)-(6)",
+ "SA-11",
+ "SA-11(2)",
+ "SA-15",
+ "SA-15(1)-(3)",
+ "SA-15(5)-(8)",
+ "SA-15(10)-(12)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.IP-2",
+ "PR.IP-12",
+ "DE.CM-8",
+ "RS.AN-5",
+ "RS.MI-3",
+ "PR.DS-6"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "ID.AM-08",
+ "ID.RA-01",
+ "ID.RA-06",
+ "ID.RA-08",
+ "PR.PS-02",
+ "PR.PS-06"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "6.2",
+ "6.5",
+ "6.5.1-10"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "6.3.1",
+ "11.3.1",
+ "11.3.1.1"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "defender_container_images_resolved_vulnerabilities",
+ "defender_container_images_scan_enabled",
+ "defender_ensure_defender_for_containers_is_on",
+ "sqlserver_va_scan_reports_configured",
+ "sqlserver_vulnerability_assessment_enabled"
+ ]
+ },
+ {
+ "Id": "BCR-08",
+ "Description": "Periodically backup data stored in the cloud. Ensure the confidentiality, integrity and availability of the backup, and verify data restoration from backup for resiliency.",
+ "Name": "Backup",
+ "Attributes": [
+ {
+ "Section": "Business Continuity Management and Operational Resilience",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "A1.2",
+ "A1.3"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "BCR-11"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "11.1",
+ "11.2",
+ "11.3",
+ "11.4",
+ "11.5"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.2.8",
+ "5.2.9"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "SY2.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.12.3",
+ "27017: 12.3",
+ "27018: 12.3.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.8.13",
+ "27001: A.5.23",
+ "27001: A.5.30",
+ "27002: 8.13",
+ "27002: 5.23 2nd (i)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "CP-4",
+ "CP-4(4)",
+ "CP-6",
+ "CP-6(1)-(3)",
+ "CP-9",
+ "CP-9(1)",
+ "CP-9(2)",
+ "CP-10",
+ "CP-10(2)",
+ "CP-10(4)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.IP-4",
+ "PR.DS-1"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.DS-01",
+ "PR.DS-11",
+ "RC.RP-03"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "9.5.1",
+ "12.10.1"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "12.10.1",
+ "10.3.3"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "storage_ensure_encryption_with_customer_managed_keys",
+ "vm_backup_enabled",
+ "vm_sufficient_daily_backup_retention_period"
+ ]
+ },
+ {
+ "Id": "BCR-09",
+ "Description": "Establish, document, approve, communicate, apply, evaluate and maintain a disaster response plan to recover from natural and man-made disasters. Update the plan at least annually or upon significant changes.",
+ "Name": "Disaster Response Plan",
+ "Attributes": [
+ {
+ "Section": "Business Continuity Management and Operational Resilience",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "A1.2",
+ "CC3.2"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.2.8",
+ "5.2.9",
+ "1.6.1",
+ "1.6.2",
+ "1.6.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "BC1.4",
+ "BC2.1",
+ "BC2.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.29",
+ "27001: A.5.30",
+ "27002: 5.29",
+ "27002: 5.30"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "CP-2(1)",
+ "CP-2(2)",
+ "CP-2(3)",
+ "CP-2(5)",
+ "CP-2(6)",
+ "CP-2(7)",
+ "CP-2(8)",
+ "PE-13",
+ "PE-13(1)",
+ "PE-13(2)",
+ "PE-13(4)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.IP-9",
+ "PR.IP-10",
+ "RC.IM-1",
+ "RC.IM-2"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "ID.IM-04"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "defender_ensure_defender_for_server_is_on",
+ "vm_backup_enabled"
+ ]
+ },
+ {
+ "Id": "BCR-11",
+ "Description": "Supplement business-critical equipment with redundant equipment independently located at a reasonable minimum distance in accordance with applicable industry standards.",
+ "Name": "Equipment Redundancy",
+ "Attributes": [
+ {
+ "Section": "Business Continuity Management and Operational Resilience",
+ "CCMLite": "No",
+ "IaaS": "CSP-Owned",
+ "PaaS": "CSP-Owned",
+ "SaaS": "CSP-Owned",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "A1.2",
+ "CC3.2"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "BCR-06"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.2.8"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "BC1.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.20",
+ "27001: A.7.11",
+ "27001: A.8.14",
+ "27002: 5.20 (t)",
+ "27002: 8.14 (c)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "CP-2",
+ "CP-2(2)",
+ "CP-4(3)",
+ "CP-6",
+ "CP-6(1)",
+ "CP-7",
+ "CP-8",
+ "CP-8(1)-(3)",
+ "CP-9",
+ "CP-9(6)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "ID.BE-4",
+ "ID.BE-5"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "GV.OC-04",
+ "GV.OC-05",
+ "PR.IR-03"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "storage_blob_versioning_is_enabled",
+ "storage_geo_redundant_enabled",
+ "vm_scaleset_associated_with_load_balancer",
+ "vm_scaleset_not_empty"
+ ]
+ },
+ {
+ "Id": "CCC-04",
+ "Description": "Restrict the unauthorized addition, removal, update, and management of organization assets.",
+ "Name": "Unauthorized Change Protection",
+ "Attributes": [
+ {
+ "Section": "Change Control and Configuration Management",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC8.1"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "CCC-04"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.2.1",
+ "1.3.4",
+ "5.3.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "SY2.4",
+ "SM2.6"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.12.1.4",
+ "27002: 12.1.4",
+ "27001: A.12.4.2",
+ "27002: 12.4.2",
+ "27001: A.14.2.2",
+ "27017: 14.2.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.8.3",
+ "27001: A.8.4",
+ "27001: A.8.15",
+ "27001: A.8.31",
+ "27001: A.8.32"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "CA-7",
+ "CA-7(4)",
+ "CM-3",
+ "CM-3(1)",
+ "CM-3(5)",
+ "CM-3(7)",
+ "CM-3(8)",
+ "CM-5",
+ "CM-5(1)",
+ "CM-5(4)",
+ "CM-5(5)",
+ "CM-6",
+ "CM-6(1)",
+ "CM-6(2)",
+ "CM-7",
+ "CM-7(1)",
+ "CM-7(4)",
+ "CM-7(5)",
+ "CM-7(9)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "ID.AM-1",
+ "ID.AM-2",
+ "ID.AM-4",
+ "PR.MA-1",
+ "PR.MA-2",
+ "PR.AC-1"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "ID.AM-01",
+ "ID.AM-02",
+ "ID.AM-04",
+ "ID.AM-08",
+ "PR.PS-02",
+ "PR.PS-03",
+ "PR.PS-05",
+ "PR.AA-05"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "6.4.5.2"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "6.5.1",
+ "6.5.2"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "iam_custom_role_has_permissions_to_administer_resource_locks",
+ "monitor_alert_create_policy_assignment",
+ "monitor_diagnostic_setting_with_appropriate_categories",
+ "monitor_diagnostic_settings_exists",
+ "policy_ensure_asc_enforcement_enabled",
+ "storage_ensure_soft_delete_is_enabled"
+ ]
+ },
+ {
+ "Id": "CCC-07",
+ "Description": "Implement detection measures with proactive notification in case of changes deviating from the established baseline.",
+ "Name": "Detection of Baseline Deviation",
+ "Attributes": [
+ {
+ "Section": "Change Control and Configuration Management",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC8.1"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "GRM-01"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "1.5.1",
+ "1.5.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "SY2.4"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.14.2.2",
+ "27001: A.14.2.4",
+ "27001: A.12.4.1",
+ "27002: 12.4.1 (g)",
+ "27001: A.5.1.1",
+ "27017: 5.1.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.8.9",
+ "27001: A.8.15",
+ "27002: 8.9"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "CM-6",
+ "CM-6(2)",
+ "SI-2",
+ "SI-2(2)-(6)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.MA-1",
+ "PR.IP-1",
+ "DE.DP-4",
+ "PR.IP-3"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.PS-01",
+ "DE.CM-09",
+ "DE.AE-06"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "6.4.5.3",
+ "6.4.5.4",
+ "11.5",
+ "11.5.1"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "11.5.2",
+ "11.6.1"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "defender_ensure_defender_for_app_services_is_on",
+ "defender_ensure_defender_for_azure_sql_databases_is_on",
+ "defender_ensure_defender_for_server_is_on",
+ "defender_ensure_wdatp_is_enabled",
+ "monitor_alert_create_policy_assignment",
+ "monitor_alert_create_update_nsg",
+ "monitor_alert_create_update_public_ip_address_rule",
+ "monitor_alert_create_update_security_solution",
+ "monitor_alert_create_update_sqlserver_fr",
+ "monitor_alert_delete_nsg",
+ "monitor_alert_delete_policy_assignment",
+ "monitor_alert_delete_public_ip_address_rule",
+ "monitor_alert_delete_security_solution",
+ "monitor_alert_delete_sqlserver_fr",
+ "monitor_diagnostic_settings_exists",
+ "policy_ensure_asc_enforcement_enabled"
+ ]
+ },
+ {
+ "Id": "CEK-03",
+ "Description": "Provide cryptographic protection to data at-rest and in-transit, using cryptographic libraries certified to approved standards.",
+ "Name": "Data Encryption",
+ "Attributes": [
+ {
+ "Section": "Cryptography, Encryption & Key Management",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC6.1",
+ "CC6.7"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "EKM-03",
+ "EKM-04"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "3.6",
+ "3.1",
+ "3.11",
+ "11.3",
+ "16.11"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.1.1",
+ "5.1.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "TS2.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.18.1.1",
+ "27001: A.18.1.2",
+ "27001: A.18.1.3",
+ "27001: A.18.1.4",
+ "27001: A.18.1.5",
+ "27001: A.10.1",
+ "27002: 10.1",
+ "27001: A.13.2.1",
+ "27002: 13.2.1",
+ "27001: A.18",
+ "27002: 18",
+ "27001: A.14.1.2",
+ "27002: 14.1.2",
+ "27001: A.14.1.3",
+ "27002 14.1.3 c)",
+ "27001 - A.10.1.1",
+ "27017 - 10.1.1",
+ "27001 - A.10.1.2",
+ "27017 - 10.1.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.14",
+ "27001: A.8.24",
+ "27002: 8.24 Other Information (a)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "AC-19",
+ "AC-19(5)",
+ "SC-8",
+ "SC-8(1)",
+ "SC-8(3)",
+ "SC-8(4)",
+ "SC-12",
+ "SC-12(2)",
+ "SC-12(3)",
+ "SC-28",
+ "SC-28(1)-(3)",
+ "SI-4",
+ "SI-4(10)",
+ "SI-7",
+ "SI-7(6)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.DS-1",
+ "PR.DS-2"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.DS-01",
+ "PR.DS-02"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "Requirement 3",
+ "2.2.3",
+ "2.3",
+ "3.4",
+ "3.5.3",
+ "4.1",
+ "8.2.1",
+ "PCI Glossary - Strong Cryptography"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "2.2.7",
+ "3.5.1",
+ "4.2.1",
+ "4.2.1.2",
+ "4.2.2"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "app_minimum_tls_version_12",
+ "databricks_workspace_cmk_encryption_enabled",
+ "mysql_flexible_server_ssl_connection_enabled",
+ "postgresql_flexible_server_enforce_ssl_enabled",
+ "sqlserver_tde_encrypted_with_cmk",
+ "sqlserver_tde_encryption_enabled",
+ "storage_ensure_encryption_with_customer_managed_keys",
+ "storage_infrastructure_encryption_is_enabled",
+ "storage_secure_transfer_required_is_enabled",
+ "storage_smb_channel_encryption_with_secure_algorithm",
+ "vm_ensure_attached_disks_encrypted_with_cmk",
+ "vm_ensure_unattached_disks_encrypted_with_cmk"
+ ]
+ },
+ {
+ "Id": "CEK-04",
+ "Description": "Use encryption algorithms that are appropriate for data protection, considering the classification of data, associated risks, and usability of the encryption technology.",
+ "Name": "Encryption Algorithm",
+ "Attributes": [
+ {
+ "Section": "Cryptography, Encryption & Key Management",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC6.1",
+ "CC6.7"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "EKM-04"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "16.11"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.1.1",
+ "5.1.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "TS2.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: 6.1.2",
+ "27001: 6.1.3",
+ "27001: A.8.2",
+ "27002: 8.2",
+ "27001: A.8.3",
+ "27001: A.10.1.1",
+ "27002: 10.1.1 (b)",
+ "27001: A.10.1.2",
+ "27002: 10.1.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: 6.1.2",
+ "27001: 6.1.3",
+ "27001: A.8.24",
+ "27001: A.5.12",
+ "27001: A.5.13",
+ "27002: 8.24 General (b)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "SC-12",
+ "SC-12(2)",
+ "SC-12(3)",
+ "SC-28",
+ "SC-28(1)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.DS-1",
+ "PR.DS-2",
+ "ID.AM-5"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.DS-01",
+ "PR.DS-02",
+ "ID.AM-05"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "A2",
+ "Requirement 3",
+ "2.3",
+ "2.2.3",
+ "3.4",
+ "3.5.3",
+ "4.1",
+ "8.2.1",
+ "PCI Glossary - Strong Cryptography"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "2.2.7",
+ "3.5.1",
+ "4.2.1",
+ "4.2.1.2",
+ "4.2.2"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "app_minimum_tls_version_12",
+ "keyvault_key_rotation_enabled",
+ "mysql_flexible_server_minimum_tls_version_12",
+ "postgresql_flexible_server_enforce_ssl_enabled",
+ "sqlserver_recommended_minimal_tls_version",
+ "storage_ensure_minimum_tls_version_12",
+ "storage_smb_protocol_version_is_latest"
+ ]
+ },
+ {
+ "Id": "CEK-08",
+ "Description": "CSPs must provide the capability for CSCs to manage their own data encryption keys.",
+ "Name": "CSC Key Management Capability",
+ "Attributes": [
+ {
+ "Section": "Cryptography, Encryption & Key Management",
+ "CCMLite": "No",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "TS2.2",
+ "SC2.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.10.1",
+ "27017: 10.1",
+ "27001: A.10.1.1",
+ "27017: 10.1.1",
+ "27001: A.10.1.2",
+ "27017: 10.1.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.23",
+ "27001: A.8.24"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "CP-9",
+ "CP-9(8)",
+ "SA-9",
+ "SA-9(6)",
+ "SC-12",
+ "SC-12(6)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "ID.SC-3",
+ "ID.AM-6",
+ "PR.AC-1"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "GV.SC-05"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "databricks_workspace_cmk_encryption_enabled",
+ "keyvault_access_only_through_private_endpoints",
+ "keyvault_private_endpoints",
+ "keyvault_rbac_enabled",
+ "storage_ensure_encryption_with_customer_managed_keys"
+ ]
+ },
+ {
+ "Id": "CEK-10",
+ "Description": "Generate Cryptographic keys using industry accepted cryptographic libraries specifying the algorithm strength and the random number generator used.",
+ "Name": "Key Generation",
+ "Attributes": [
+ {
+ "Section": "Cryptography, Encryption & Key Management",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "EKM-04"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "16.11"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.1.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "TS2.2",
+ "TS2.3",
+ "SY1.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.10.1.1",
+ "27002: 10.1.1 (e)",
+ "27017: 10.1.1",
+ "27001: A.10.1.2",
+ "27002: 10.1.2",
+ "27002: 10.1.2 (a)",
+ "27017: 10.1.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.8.24",
+ "27002: 8.24 (d), Key management (a)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "SC-12",
+ "SC-12(2)",
+ "SC-12(3)",
+ "SC-13"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.AC-1"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.AA-01",
+ "PR.AA-05"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "2.2.3",
+ "3.6.1",
+ "PCI Glossary - Cryptographic Key Generation"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "3.6.1",
+ "3.6.1.1",
+ "3.7.1"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "keyvault_rbac_enabled",
+ "storage_ensure_encryption_with_customer_managed_keys"
+ ]
+ },
+ {
+ "Id": "CEK-12",
+ "Description": "Rotate cryptographic keys in accordance with the calculated cryptoperiod, which includes provisions for considering the risk of information disclosure and legal and regulatory requirements.",
+ "Name": "Key Rotation",
+ "Attributes": [
+ {
+ "Section": "Cryptography, Encryption & Key Management",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.1.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "TS2.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.10.1.1",
+ "27017: 10.1.1",
+ "27001: A.10.1.2",
+ "27002: 10.1.2 e)",
+ "27017: 10.1.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.31",
+ "27001: A.8.24",
+ "27002: 5.31 Cryptography",
+ "27002: 8.24 Key management (e,m)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "SC-12",
+ "SC-12(2)",
+ "SC-12(3)",
+ "SC-13"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.AC-1",
+ "ID.GV-3"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.AA-01",
+ "PR.AA-05",
+ "GV.OC-03"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "3.7.4",
+ "3.7.5"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "keyvault_key_expiration_set_in_non_rbac",
+ "keyvault_key_rotation_enabled",
+ "keyvault_non_rbac_secret_expiration_set",
+ "keyvault_rbac_key_expiration_set",
+ "keyvault_rbac_secret_expiration_set",
+ "storage_key_rotation_90_days"
+ ]
+ },
+ {
+ "Id": "CEK-14",
+ "Description": "Define, implement and evaluate processes, procedures and technical measures to destroy keys stored outside a secure environment and revoke keys stored in Hardware Security Modules (HSMs) when they are no longer needed, which include provisions for legal and regulatory requirements.",
+ "Name": "Key Destruction",
+ "Attributes": [
+ {
+ "Section": "Cryptography, Encryption & Key Management",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.1.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "TS2.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.10.1.1",
+ "27017: 10.1.1",
+ "27017: 10.1.2",
+ "27001: A.10.1.2",
+ "27002: 10.1.2 (j)",
+ "27001: A.18.1.3",
+ "27002: 18.1.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.31",
+ "27001: A.8.24",
+ "27002: 5.31 Cryptography",
+ "27002: 8.24 Key management (j,m)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "SC-12",
+ "SC-12(2)",
+ "SC-12(3)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.AC-1",
+ "PR.IP-6",
+ "ID.GV-3",
+ "PR.DS-3"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.AA-01",
+ "PR.AA-05",
+ "ID.AM-08",
+ "GV.OC-03"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "3.6.4",
+ "3.6.5"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "3.7.4",
+ "3.7.5"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "keyvault_recoverable"
+ ]
+ },
+ {
+ "Id": "DCS-06",
+ "Description": "Catalogue and track all relevant physical and logical assets located at all of the CSP's sites within a secured system.",
+ "Name": "Assets Cataloguing and Tracking",
+ "Attributes": [
+ {
+ "Section": "Datacenter Security",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC6.1"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "DCS - 01"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "1.1",
+ "2.1"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "1.3.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "SM2.6"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.8.1.1",
+ "27002: 8.1.1",
+ "27017: 8.1.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.9"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "CM-8",
+ "CM-8(1)",
+ "CM-8(2)",
+ "CM-8(4)",
+ "CM-8(7)",
+ "CM-8(8)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "ID.AM-1",
+ "ID.AM-2",
+ "ID.AM-4",
+ "PR.AC-4"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "ID.AM-01",
+ "ID.AM-02",
+ "ID.AM-04"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "2.4",
+ "9.7.1",
+ "9.9.1",
+ "9.9.1.a",
+ "9.9.1.b",
+ "9.9.1.c",
+ "12.3.3",
+ "12.3.4"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "3.6.1.1",
+ "6.3.2",
+ "9.4.2",
+ "9.4.3",
+ "12.5.1"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "defender_ensure_mcas_is_enabled",
+ "monitor_diagnostic_settings_exists",
+ "policy_ensure_asc_enforcement_enabled"
+ ]
+ },
+ {
+ "Id": "DSP-02",
+ "Description": "Apply industry accepted methods for the secure disposal of data from storage media such that data is not recoverable by any forensic means.",
+ "Name": "Secure Disposal",
+ "Attributes": [
+ {
+ "Section": "Data Security and Privacy Lifecycle Management",
+ "CCMLite": "No",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC6.1",
+ "CC6.2",
+ "CC6.3",
+ "CC6.4",
+ "CC6.5",
+ "CC6.7",
+ "P4.3"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "DSI-07"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "3.5"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.1.1",
+ "5.3.3",
+ "7.1.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "IM1.1",
+ "IM1.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.8.3.2",
+ "27002: 8.3.2",
+ "27001: A.11.2.7",
+ "27002: 11.2.7"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.7.10",
+ "27001: A.7.14",
+ "27001: A.8.10",
+ "27002: 7.10 (Secure reuse or disposal)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "PM-22",
+ "SI-12",
+ "SI-12(3)",
+ "SI-18",
+ "SI-18(1)",
+ "SI-18(4)",
+ "SI-18(5)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.IP-6"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "GV.SC-10",
+ "PR.PS-02",
+ "PR.PS-03",
+ "ID.AM-08"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "3.1",
+ "9.8",
+ "9.8.1",
+ "9.8.2"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "3.2.1",
+ "3.7.5",
+ "9.4.7"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "storage_ensure_file_shares_soft_delete_is_enabled",
+ "storage_ensure_soft_delete_is_enabled",
+ "vm_sufficient_daily_backup_retention_period"
+ ]
+ },
+ {
+ "Id": "DSP-03",
+ "Description": "Create and maintain a data inventory, at least for any sensitive data and personal data.",
+ "Name": "Data Inventory",
+ "Attributes": [
+ {
+ "Section": "Data Security and Privacy Lifecycle Management",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC6.1"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "3.2"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "1.3.1",
+ "1.3.2",
+ "1.3.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "IM1.1",
+ "IM2.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.8.1.1",
+ "27002: 8.1.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.9",
+ "27001: A.8.12"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "CM-12",
+ "CM-12(1)",
+ "PM-5",
+ "PM-5(1)",
+ "SI-12",
+ "SI-12(1)",
+ "SI-19",
+ "SI-19(1)",
+ "SI-19(2)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "ID.AM-5"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "ID.AM-07"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "3.2.1",
+ "9.4.5"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "defender_ensure_defender_for_storage_is_on",
+ "defender_ensure_mcas_is_enabled",
+ "monitor_diagnostic_settings_exists",
+ "policy_ensure_asc_enforcement_enabled"
+ ]
+ },
+ {
+ "Id": "DSP-04",
+ "Description": "Classify data according to its type and sensitivity level.",
+ "Name": "Data Classification",
+ "Attributes": [
+ {
+ "Section": "Data Security and Privacy Lifecycle Management",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC6.1",
+ "C1.1"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "DSI-01"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "3.7"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "1.3.1",
+ "1.3.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "IM1.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.8.2.1",
+ "27002: 8.2.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.12"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "AC-16",
+ "AC-16(9)",
+ "PM-22",
+ "PM-23",
+ "PT-2",
+ "PT-2(1)",
+ "SI-18",
+ "SI-18(2)",
+ "SI-19",
+ "SI-19(6)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "ID.AM-5"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "ID.AM-05",
+ "ID.AM-07"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "9.6.1"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "9.4.2",
+ "9.4.3"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "defender_ensure_defender_for_storage_is_on"
+ ]
+ },
+ {
+ "Id": "DSP-07",
+ "Description": "Develop systems, products, and business practices based upon a principle of security by design and industry best practices.",
+ "Name": "Data Protection by Design and Default",
+ "Attributes": [
+ {
+ "Section": "Data Security and Privacy Lifecycle Management",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "PI1.2",
+ "PI1.3"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "16.1"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.3.1",
+ "5.3.2",
+ "5.3.3",
+ "5.3.4"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "SD2.2",
+ "IM1.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.14.1.1",
+ "27002:14.1.1",
+ "27001: A.14.2.5",
+ "27002:14.2.5"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.8.27",
+ "27001: A.8.28",
+ "27001: A.8.29",
+ "27002: 5.8 (Information security requirements a-i)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "PM-17",
+ "PM-24",
+ "PM-25",
+ "PT-2",
+ "PT-2(2)",
+ "SA-3",
+ "SA-4",
+ "SA-5",
+ "SA-8",
+ "SA-8(9)",
+ "SA-8(13)",
+ "SA-8(18)",
+ "SA-8(20)",
+ "SA-8(22)",
+ "SA-8(23)",
+ "SA-8(33)",
+ "SA-15",
+ "SA-15(12)",
+ "SC-3",
+ "SC-3(3)",
+ "SC-7",
+ "SC-7(24)",
+ "SC-8",
+ "SC-8(1)-(4)",
+ "SC-28",
+ "SC-28(1)",
+ "SI-12",
+ "SI-12(1)-(3)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.IP-2",
+ "PR.PT-3",
+ "PR.AC-4"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "ID.AM-08",
+ "PR.PS-06"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "6.2.1"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "aisearch_service_not_publicly_accessible",
+ "aks_clusters_public_access_disabled",
+ "containerregistry_not_publicly_accessible",
+ "cosmosdb_account_firewall_use_selected_networks",
+ "sqlserver_unrestricted_inbound_access",
+ "storage_blob_public_access_level_is_disabled",
+ "storage_default_network_access_rule_is_denied",
+ "storage_ensure_private_endpoints_in_storage_accounts",
+ "vm_ensure_attached_disks_encrypted_with_cmk",
+ "vm_ensure_unattached_disks_encrypted_with_cmk"
+ ]
+ },
+ {
+ "Id": "DSP-10",
+ "Description": "Define, implement and evaluate processes, procedures and technical measures that ensure any transfer of personal or sensitive data is protected from unauthorized access and only processed within scope as permitted by the respective laws and regulations.",
+ "Name": "Sensitive Data Transfer",
+ "Attributes": [
+ {
+ "Section": "Data Security and Privacy Lifecycle Management",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC6.7"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "GRM-02",
+ "EKM-03"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "3.1",
+ "3.12",
+ "3.13"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.1.2",
+ "9.5.1",
+ "9.5.2",
+ "9.5.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "IM1.4",
+ "IM2.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.13.2.1",
+ "27002: 13.2.1",
+ "27001: A.8.3.3",
+ "27002: 8.3.3",
+ "27001: A.13.2.3",
+ "27002: 13.2.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.14",
+ "27001: A.7.10"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "AC-4",
+ "AC-4(23)-(25)",
+ "CA-3",
+ "CA-3(6)",
+ "CA-6",
+ "CA-6(1)",
+ "CA-6(2)",
+ "SC-4",
+ "SC-4(2)",
+ "SC-7",
+ "SC-7(10)",
+ "SC-7(24)",
+ "SC-8",
+ "SC-8(1)-(5)",
+ "SC-16",
+ "SC-16(1)-(3)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.DS-2",
+ "PR.DS-5",
+ "PR.PT-4"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.DS-02",
+ "PR.IR-01",
+ "ID.AM-03",
+ "GV.OC-03",
+ "ID.AM-07"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "4.1"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "4.1.1",
+ "4.2.1",
+ "4.2.2"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "app_ensure_http_is_redirected_to_https",
+ "app_ensure_using_http20",
+ "sqlserver_recommended_minimal_tls_version",
+ "storage_ensure_minimum_tls_version_12",
+ "storage_secure_transfer_required_is_enabled"
+ ]
+ },
+ {
+ "Id": "DSP-16",
+ "Description": "Data retention, archiving and deletion is managed in accordance with business requirements, applicable laws and regulations.",
+ "Name": "Data Retention and Deletion",
+ "Attributes": [
+ {
+ "Section": "Data Security and Privacy Lifecycle Management",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "C1.1",
+ "C1.2",
+ "CC3.1",
+ "P4.2"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "GRM-02",
+ "BCR-11"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "3.4",
+ "3.5"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.1.1",
+ "5.3.1",
+ "7.1.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "IM1.1",
+ "IM2.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.18.1.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.33",
+ "27001: A.8.10",
+ "27002: 5.33 (b)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "SI-12",
+ "SI-12(1)-(3)",
+ "SI-18",
+ "SI-18(1)",
+ "SI-18(4)",
+ "SI-18(5)",
+ "SI-19",
+ "SI-19(2)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.DS-3",
+ "PR.IP-6",
+ "ID.GV-3"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "ID.AM-08",
+ "GV.OC-03",
+ "GV.SC-10",
+ "PR.DS-11"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "3.1"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "3.2.1"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "monitor_storage_account_with_activity_logs_cmk_encrypted",
+ "monitor_storage_account_with_activity_logs_is_private",
+ "postgresql_flexible_server_log_retention_days_greater_3",
+ "sqlserver_auditing_retention_90_days",
+ "storage_ensure_file_shares_soft_delete_is_enabled",
+ "storage_ensure_soft_delete_is_enabled"
+ ]
+ },
+ {
+ "Id": "DSP-17",
+ "Description": "Define and implement, processes, procedures and technical measures to protect sensitive data throughout it's lifecycle.",
+ "Name": "Sensitive Data Protection",
+ "Attributes": [
+ {
+ "Section": "Data Security and Privacy Lifecycle Management",
+ "CCMLite": "Yes",
+ "IaaS": "CSP-Owned",
+ "PaaS": "CSP-Owned",
+ "SaaS": "CSC-Owned",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC2.1",
+ "CC6.1",
+ "CC6.3",
+ "CC6.7",
+ "CC8.1",
+ "C1.1",
+ "P2.0",
+ "P3.0",
+ "P4.0",
+ "P5.0",
+ "P6.0"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "3.1",
+ "3.1",
+ "3.14"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.3.3",
+ "9.1.1",
+ "9.2.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "IM1.1",
+ "IM2.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.18.1.3",
+ "27002: 18.1.3",
+ "27001:A.18.1.4",
+ "27002:18.1.4"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.8.11",
+ "27001: A.8.12"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "PL-2",
+ "PM-22",
+ "PM-24",
+ "PT-7",
+ "PT-7(1)",
+ "PT-7(2)",
+ "PT-8",
+ "SC-8",
+ "SC-8(1)-(5)",
+ "SC-28",
+ "SC-28(1)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.DS-1",
+ "PR.DS-2",
+ "PR.DS-5"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.DS-01",
+ "PR.DS-02",
+ "PR.DS-10"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "3.0 (including all subsections)",
+ "4.0 (including all subsections)"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "3.1.1",
+ "4.1.1"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "containerregistry_not_publicly_accessible",
+ "cosmosdb_account_firewall_use_selected_networks",
+ "defender_ensure_defender_for_storage_is_on",
+ "sqlserver_tde_encrypted_with_cmk",
+ "sqlserver_tde_encryption_enabled",
+ "sqlserver_unrestricted_inbound_access",
+ "storage_account_key_access_disabled",
+ "storage_blob_public_access_level_is_disabled",
+ "storage_cross_tenant_replication_disabled",
+ "storage_default_network_access_rule_is_denied",
+ "storage_default_to_entra_authorization_enabled",
+ "storage_ensure_encryption_with_customer_managed_keys",
+ "vm_ensure_attached_disks_encrypted_with_cmk"
+ ]
+ },
+ {
+ "Id": "GRC-05",
+ "Description": "Develop and implement an Information Security Program, which includes programs for all the relevant domains of the CCM.",
+ "Name": "Information Security Program",
+ "Attributes": [
+ {
+ "Section": "Governance, Risk and Compliance",
+ "CCMLite": "No",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "GRM-04"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "14.1"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "1.2.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "SG2.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: 4.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: 4.3"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "PM-1",
+ "PM-3",
+ "PM-14",
+ "PL-2",
+ "PM-18",
+ "PM-31"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "12.4.1",
+ "A.3.1"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "12.4.1",
+ "A3.1.1"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "defender_ensure_defender_for_app_services_is_on",
+ "defender_ensure_defender_for_arm_is_on",
+ "defender_ensure_defender_for_azure_sql_databases_is_on",
+ "defender_ensure_defender_for_databases_is_on",
+ "defender_ensure_defender_for_dns_is_on",
+ "defender_ensure_defender_for_keyvault_is_on",
+ "defender_ensure_defender_for_server_is_on",
+ "defender_ensure_mcas_is_enabled",
+ "defender_ensure_wdatp_is_enabled"
+ ]
+ },
+ {
+ "Id": "IAM-02",
+ "Description": "Establish, document, approve, communicate, implement, apply, evaluate and maintain strong password policies and procedures. Review and update the policies and procedures at least annually.",
+ "Name": "Strong Password Policy and Procedures",
+ "Attributes": [
+ {
+ "Section": "Identity & Access Management",
+ "CCMLite": "No",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "IAM-02",
+ "IAM-12",
+ "GRM-06",
+ "GRM-09"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "5.2"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "1.1.1",
+ "1.5.1",
+ "4.1.2",
+ "4.1.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "SA1.1",
+ "SA1.5"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: 5.1",
+ "27001: 5.2",
+ "27001: 7.3",
+ "27001: 7.4",
+ "27001: 7.5",
+ "27001: 9.1",
+ "27001: 9.3",
+ "27001: A.5",
+ "27002: 5",
+ "27001: A.9.4.3",
+ "27002: 9.4.3",
+ "27017: 9.4.3",
+ "27018: 9.4.3",
+ "27001: A.9.2.4",
+ "27002: 9.2.4",
+ "27017: 9.2.4",
+ "27001: A.7.2.2",
+ "27002: 7.2.2",
+ "27001: A.9.2.6",
+ "27002: 9.2.6",
+ "27001: A.9.2.3",
+ "27002: 9.2.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: 5.1",
+ "27001: 5.2",
+ "27001: 7.3",
+ "27001: 7.4",
+ "27001: 7.5",
+ "27001: 9.1",
+ "27001: 9.3",
+ "27001: A.5.1",
+ "27001: A.5.4",
+ "27001: A.5.17",
+ "27001: A.6.3",
+ "27001: A.8.5",
+ "27001: A.5.37"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "AC-2",
+ "AC-2(3)",
+ "AC-2(11)",
+ "AC-3",
+ "AC-3(3)",
+ "AC-12",
+ "AC-12(1)",
+ "IA-2",
+ "IA-2(10)",
+ "IA-5",
+ "IA-5(1)",
+ "IA-5(18)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "ID.GV-1",
+ "PR.AC-1",
+ "PR.AC-7"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "GV.PO-01",
+ "GV.PO-02",
+ "ID.IM-03",
+ "PR.AA-03"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "8.4",
+ "12.1",
+ "12.1.1",
+ "12.11"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "8.1.1",
+ "8.3.8"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "entra_privileged_user_has_mfa",
+ "entra_security_defaults_enabled"
+ ]
+ },
+ {
+ "Id": "IAM-03",
+ "Description": "Manage, store, and review the information of system identities, and level of access.",
+ "Name": "Identity Inventory",
+ "Attributes": [
+ {
+ "Section": "Identity & Access Management",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC6.1",
+ "CC6.3"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "IAM-04",
+ "IAM-08",
+ "IAM-10"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "5.1",
+ "5.2"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "4.1.3",
+ "4.2.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "SA1.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: 9.2 (c)",
+ "27001: A.8.1.1",
+ "27002: 8.1.1",
+ "27001: A.9.4.1",
+ "27002: 9.4.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: 9.2 (c)",
+ "27001: A.5.15",
+ "27001: A.5.16",
+ "27001: A.5.18",
+ "27001: A.7.4",
+ "27001: A.8.15",
+ "27001: A.8.2",
+ "27001: A.8.3"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "AU-10",
+ "AU-10(1)",
+ "AU-10(2)",
+ "AU-16",
+ "AU-16(1)",
+ "IA-4",
+ "IA-4(8)",
+ "IA-4(9)",
+ "IA-5",
+ "IA-5(5)",
+ "IA-8",
+ "IA-8(4)",
+ "PM-5(1)",
+ "SA-8",
+ "SA-8(22)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.AC-1",
+ "PR.AC-6",
+ "PR.AC-4"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.AA-01",
+ "PR.AA-02",
+ "PR.AA-04",
+ "PR.AA-05"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "2.4.a"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "7.2.5",
+ "7.2.5.1"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "entra_global_admin_in_less_than_five_users"
+ ]
+ },
+ {
+ "Id": "IAM-04",
+ "Description": "Employ the separation of duties principle when implementing information system access.",
+ "Name": "Separation of Duties",
+ "Attributes": [
+ {
+ "Section": "Identity & Access Management",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC1.3",
+ "CC5.1",
+ "CC6.3"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "IAM-05"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "6.8"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "1.2.2",
+ "4.2.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "SA1.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.6.1.2",
+ "27002: 6.1.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.15",
+ "27001: A.5.18",
+ "27001: A.5.3",
+ "27001: A.8.2"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "AC-2",
+ "AC-2(3)",
+ "AC-2(11)",
+ "AC-6",
+ "AC-6(1)-(10)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.AC-4"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.AA-05"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "6.4",
+ "6.4.2"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "6.5.3",
+ "6.5.4",
+ "7.2.1",
+ "7.2.2"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "entra_policy_default_users_cannot_create_security_groups",
+ "entra_policy_ensure_default_user_cannot_create_apps",
+ "iam_role_user_access_admin_restricted",
+ "iam_subscription_roles_owner_custom_not_created"
+ ]
+ },
+ {
+ "Id": "IAM-05",
+ "Description": "Employ the least privilege principle when implementing information system access.",
+ "Name": "Least Privilege",
+ "Attributes": [
+ {
+ "Section": "Identity & Access Management",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC6.3"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "IAM-02",
+ "IAM-06",
+ "IVS-11"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "6.8"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "4.2.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "SA1.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.9.1.1",
+ "27002: 9.1.1",
+ "27001: A.9.1.2",
+ "27002: 9.1.2",
+ "27001: A.9.2.3",
+ "27002: 9.2.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.15",
+ "27001: A.8.2",
+ "27002: 5.15 (Other information 2nd (a))"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "AC-6",
+ "AC-6(4)",
+ "IA-12",
+ "IA-12(2)",
+ "IA-12(3)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.AC-4"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.AA-05"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "7.1",
+ "7.1.1",
+ "7.1.2"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "7.2.1",
+ "7.2.2",
+ "7.2.5",
+ "7.2.6"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "app_function_identity_without_admin_privileges",
+ "entra_policy_ensure_default_user_cannot_create_apps",
+ "entra_policy_ensure_default_user_cannot_create_tenants",
+ "entra_policy_restricts_user_consent_for_apps",
+ "iam_custom_role_has_permissions_to_administer_resource_locks",
+ "iam_subscription_roles_owner_custom_not_created"
+ ]
+ },
+ {
+ "Id": "IAM-07",
+ "Description": "De-provision or respectively modify access of movers / leavers or system identity changes in a timely manner in order to effectively adopt and communicate identity and access management policies.",
+ "Name": "User Access Changes and Revocation",
+ "Attributes": [
+ {
+ "Section": "Identity & Access Management",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC5.3",
+ "CC6.3"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "IAM-11"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "5.3",
+ "6.2"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "4.2.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "SA1.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.15",
+ "27001: A.5.18"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "AC-2",
+ "AC-2(1)",
+ "AC-2(2)",
+ "AC-2(6)",
+ "AC-2(8)",
+ "AC-3",
+ "AC-3(8)",
+ "AC-6",
+ "AC-6(7)",
+ "AU-10",
+ "AU-10(4)",
+ "AU-16",
+ "AU-16(1)",
+ "CM-7",
+ "CM-7(1)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.AC-1",
+ "PR.AC-4",
+ "PR.IP-11"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "GV.RR-04",
+ "GV.SC-10",
+ "PR.AA-01",
+ "PR.AA-05"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "8.1.2",
+ "8.1.3"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "8.2.5",
+ "8.2.6"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "entra_global_admin_in_less_than_five_users"
+ ]
+ },
+ {
+ "Id": "IAM-08",
+ "Description": "Review and revalidate user access for least privilege and separation of duties with a frequency that is commensurate with organizational risk tolerance.",
+ "Name": "User Access Review",
+ "Attributes": [
+ {
+ "Section": "Identity & Access Management",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC6.2",
+ "CC6.3"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "IAM-10"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "5.1"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "4.2.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "SA1.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.9.2.5",
+ "27001: A.9.2.6",
+ "27001: A.9.4.1",
+ "27017: 9.4.1",
+ "27001: A.6.1.2",
+ "27001: A 9.2.5"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.3",
+ "27001: A.5.18",
+ "27001: A.8.3"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "AC-6",
+ "AC-6(4)",
+ "AC-6(8)",
+ "IA-8",
+ "IA-8(4)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.AC-4"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.AA-05"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "12.5.5"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "7.2.5.1",
+ "7.2.5",
+ "7.2.4"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "entra_global_admin_in_less_than_five_users",
+ "keyvault_non_rbac_secret_expiration_set",
+ "keyvault_rbac_secret_expiration_set",
+ "storage_key_rotation_90_days"
+ ]
+ },
+ {
+ "Id": "IAM-09",
+ "Description": "Define, implement and evaluate processes, procedures and technical measures for the segregation of privileged access roles such that administrative access to data, encryption and key management capabilities and logging capabilities are distinct and separated.",
+ "Name": "Segregation of Privileged Access Roles",
+ "Attributes": [
+ {
+ "Section": "Identity & Access Management",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC5.1",
+ "CC6.1",
+ "CC6.3"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "5.4"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "SA1.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.9.2.3",
+ "27002: 9.2.3",
+ "27017: 9.2.3",
+ "27018: 9.2.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.8.2",
+ "27001: A.8.18",
+ "27002: 8.2 (j)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "AC-6",
+ "AC-3(7)",
+ "AC-6(4)",
+ "AC-6(8)",
+ "IA-5",
+ "IA-5(6)",
+ "IA-8",
+ "IA-8(4)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.AC-1",
+ "PR.AC-4"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.AA-01",
+ "PR.AA-05"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "2.3",
+ "3.5.2",
+ "7.1.2",
+ "7.1.1"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "3.6.1",
+ "3.7.6",
+ "6.5.3",
+ "6.5.4",
+ "7.2.1",
+ "7.2.2",
+ "10.3.1"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "entra_global_admin_in_less_than_five_users",
+ "entra_policy_guest_invite_only_for_admin_roles",
+ "entra_policy_guest_users_access_restrictions",
+ "iam_custom_role_has_permissions_to_administer_resource_locks",
+ "iam_subscription_roles_owner_custom_not_created"
+ ]
+ },
+ {
+ "Id": "IAM-10",
+ "Description": "Define and implement an access process to ensure privileged access roles and rights are granted for a time limited period, and implement procedures to prevent the culmination of segregated privileged access.",
+ "Name": "Management of Privileged Access Roles",
+ "Attributes": [
+ {
+ "Section": "Identity & Access Management",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC6.1",
+ "CC6.2",
+ "CC6.3"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "5.1",
+ "6.5"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "SA1.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.9.2.3",
+ "27002: 9.2.3",
+ "27017: 9.2.3",
+ "27018: 9.2.3",
+ "27001: A.9.4.4",
+ "27002: 9.4.4",
+ "27017: 9.4.4"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.8.2",
+ "27001: A.8.18",
+ "27002: 8.2 (i)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "AC-2",
+ "AC-2(7)",
+ "AC-3",
+ "AC-3(4)",
+ "AC-3(11)",
+ "AC-3(13)",
+ "AC-3(14)",
+ "AC-6",
+ "AC-6(4)",
+ "AC-6(5)",
+ "AC-6(8)",
+ "AC-12",
+ "AC-12(3)",
+ "AC-17",
+ "AC-17(4)",
+ "IA-8",
+ "IA-8(4)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.AC-4"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.AA-05"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "7.1"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "7.2.1",
+ "7.2.2"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "entra_conditional_access_policy_require_mfa_for_management_api",
+ "entra_global_admin_in_less_than_five_users",
+ "entra_user_with_vm_access_has_mfa",
+ "iam_role_user_access_admin_restricted",
+ "iam_subscription_roles_owner_custom_not_created",
+ "vm_jit_access_enabled"
+ ]
+ },
+ {
+ "Id": "IAM-12",
+ "Description": "Define, implement and evaluate processes, procedures and technical measures to ensure the logging infrastructure is read-only for all with write access, including privileged access roles, and that the ability to disable it is controlled through a procedure that ensures the segregation of duties and break glass procedures.",
+ "Name": "Safeguard Logs Integrity",
+ "Attributes": [
+ {
+ "Section": "Identity & Access Management",
+ "CCMLite": "No",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "3.3"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "4.2.1",
+ "5.2.4"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "TM1.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.12.4.1",
+ "27002: 12.4.1",
+ "27017: 12.4.1",
+ "27018: 12.4.1",
+ "27001: A.12.4.2",
+ "27002: 12.4.2",
+ "27017: 12.4.2",
+ "27018: 12.4.2",
+ "27001: A.12.4.3",
+ "27002: 12.4.3",
+ "27017: 12.4.3",
+ "27018: 12.4.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.8.15",
+ "27001: A.8.18",
+ "27002: 8.15 Protection of Logs"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "AC-2",
+ "AC-2(11)",
+ "AC-2(12)",
+ "IA-8",
+ "IA-8(4)",
+ "SA-8",
+ "SA-8(22)",
+ "SC-34",
+ "SC-34(1)",
+ "SC-34(2)",
+ "SC-36",
+ "SI-4",
+ "SI-4(5)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.AC-4"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.AA-05"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "10.5"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "10.3.1",
+ "10.3.2",
+ "10.3.3",
+ "10.3.4"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "entra_trusted_named_locations_exists",
+ "keyvault_logging_enabled",
+ "monitor_diagnostic_setting_with_appropriate_categories",
+ "monitor_storage_account_with_activity_logs_is_private"
+ ]
+ },
+ {
+ "Id": "IAM-13",
+ "Description": "Define, implement and evaluate processes, procedures and technical measures that ensure users are identifiable through unique IDs or which can associate individuals to the usage of user IDs.",
+ "Name": "Uniquely Identifiable Users",
+ "Attributes": [
+ {
+ "Section": "Identity & Access Management",
+ "CCMLite": "No",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC6.1"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "4.1.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "SA1.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.9.2.1",
+ "27002: 9.2.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.16"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "AC-3",
+ "AC-3(14)",
+ "AC-24",
+ "AC-24(2)",
+ "AU-10",
+ "AU-10(1)",
+ "IA-2",
+ "IA-2(1)",
+ "IA-2(2)",
+ "IA-2(12)",
+ "IA-4",
+ "IA-4(1)",
+ "SA-8",
+ "SA-8(22)",
+ "SC-23",
+ "SC-23(3)",
+ "SC-40(4)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.AC-1",
+ "PR.AC-6"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.AA-01",
+ "PR.AA-02"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "8.1",
+ "8.2",
+ "8.6"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "8.2.1",
+ "8.2.2",
+ "8.2.4"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "entra_conditional_access_policy_require_mfa_for_management_api",
+ "entra_non_privileged_user_has_mfa",
+ "entra_privileged_user_has_mfa",
+ "entra_security_defaults_enabled",
+ "postgresql_flexible_server_entra_id_authentication_enabled",
+ "sqlserver_azuread_administrator_enabled"
+ ]
+ },
+ {
+ "Id": "IAM-14",
+ "Description": "Define, implement and evaluate processes, procedures and technical measures for authenticating access to systems, application and data assets, including multifactor authentication for at least privileged user and sensitive data access. Adopt digital certificates or alternatives which achieve an equivalent level of security for system identities.",
+ "Name": "Strong Authentication",
+ "Attributes": [
+ {
+ "Section": "Identity & Access Management",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC6.1",
+ "CC6.2"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "IAM-02",
+ "IAM-05"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "6.3",
+ "6.5",
+ "12.5",
+ "12.7"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "4.1.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "SA1.3",
+ "SA1.4",
+ "SA1.8"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.9.1.2",
+ "27002: 9.1.2",
+ "27017: 9.1.2",
+ "27001: A.9.2.4",
+ "27002: 9.2.4",
+ "27017: 9.2.4",
+ "27001: A.9.4.2",
+ "27002: 9.4.2",
+ "27017: 9.4.2",
+ "27018: 9.4.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.15",
+ "27001: A.5.17",
+ "27001: A.8.5",
+ "27001: A.8.24",
+ "27002: 8.5",
+ "27002: 8.24 other information (d)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "AC-6",
+ "AC-6(5)",
+ "AC-7",
+ "AC-7(4)",
+ "AU-10",
+ "AU-10(2)",
+ "IA-2",
+ "IA-2(1)",
+ "IA-2(2)",
+ "IA-2(8)",
+ "IA-2(12)",
+ "IA-3",
+ "IA-3(1)",
+ "IA-5",
+ "IA-5(2)",
+ "IA-5(7)",
+ "IA-5(9)",
+ "IA-5(10)",
+ "IA-5(12)",
+ "IA-5(14)-(16)",
+ "IA-8",
+ "IA-8(1)",
+ "IA-8(6)",
+ "SC-23",
+ "SC-23(3)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.AC-1",
+ "PR.AC-6",
+ "PR.AC-7"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.AA-01",
+ "PR.AA-02",
+ "PR.AA-03"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "8.1.2",
+ "8.1.3",
+ "8.1.6",
+ "8.2",
+ "8.3",
+ "8.3.2",
+ "12.3.2"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "7.2.1",
+ "8.3.1",
+ "8.3.2",
+ "8.4.1",
+ "8.4.2",
+ "8.4.3"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "entra_non_privileged_user_has_mfa",
+ "entra_privileged_user_has_mfa",
+ "entra_security_defaults_enabled",
+ "entra_user_with_vm_access_has_mfa"
+ ]
+ },
+ {
+ "Id": "IAM-15",
+ "Description": "Define, implement and evaluate processes, procedures and technical measures for the secure management of passwords.",
+ "Name": "Passwords Management",
+ "Attributes": [
+ {
+ "Section": "Identity & Access Management",
+ "CCMLite": "No",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC6.1",
+ "CC6.2"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "4.1.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "SA1.5"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.9.2.4",
+ "27002: 9.2.4",
+ "27017: 9.2.4",
+ "27018: 9.2.4",
+ "27001: A.9.3.1",
+ "27002: 9.3.1",
+ "27017: 9.3.1",
+ "27018: 9.3.1",
+ "27001: A.9.4.3",
+ "27002: 9.4.3",
+ "27017: 9.4.3",
+ "27018: 9.4.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.17"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "IA-4",
+ "IA-4(8)",
+ "IA-5",
+ "IA-5(1)",
+ "IA-5(8)",
+ "IA-5(18)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.AC-1"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.AA-01"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "8.2",
+ "8.2.1-6"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "2.2.2",
+ "2.3.1",
+ "8.3.5",
+ "8.3.6",
+ "8.3.7",
+ "8.3.8",
+ "8.3.9",
+ "8.3.10",
+ "8.3.10.1",
+ "8.6.2"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "entra_privileged_user_has_mfa",
+ "entra_security_defaults_enabled"
+ ]
+ },
+ {
+ "Id": "IAM-16",
+ "Description": "Define, implement and evaluate processes, procedures and technical measures to verify access to data and system functions is authorized.",
+ "Name": "Authorization Mechanisms",
+ "Attributes": [
+ {
+ "Section": "Identity & Access Management",
+ "CCMLite": "No",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC6.1",
+ "CC6.2",
+ "CC6.3"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "IAM-02"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "5.1"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "4.2.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "SA1.3",
+ "SA1.4"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.9.2.5",
+ "27002: 9.2.5",
+ "27017: 9.2.5",
+ "27018: 9.2.5"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.18"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "AC-3",
+ "AC-3(5)",
+ "AC-4",
+ "AC-4(17)",
+ "AC-4(21)",
+ "AC-4(22)",
+ "AC-6",
+ "AC-6(8)",
+ "AC-6(9)",
+ "AC-12",
+ "AC-12(1)",
+ "AC-20",
+ "AC-20(1)",
+ "AU-10",
+ "AU-10(1)",
+ "AU-10(2)",
+ "IA-2",
+ "IA-2(1)",
+ "IA-2(2)",
+ "IA-2(12)",
+ "IA-3",
+ "IA-3(1)",
+ "IA-5(1)",
+ "IA-5(2)",
+ "IA-5(5)",
+ "IA-5(8)",
+ "IA-5(10)",
+ "IA-5(12)",
+ "IA-8",
+ "IA-8(1)",
+ "IA-8(2)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.AC-1",
+ "PR.AC-4",
+ "PR.AC-6",
+ "PR.AC-7",
+ "PR.PT-1"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.AA-01",
+ "PR.AA-02",
+ "PR.AA-03",
+ "PR.AA-04",
+ "PR.AA-05",
+ "PR.PS-04"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "5.3",
+ "7.1.4"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "7.2.4",
+ "7.2.3",
+ "7.2.5.1"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "aks_cluster_rbac_enabled",
+ "app_function_identity_is_configured",
+ "app_function_identity_without_admin_privileges",
+ "app_function_not_publicly_accessible",
+ "entra_policy_user_consent_for_verified_apps",
+ "iam_subscription_roles_owner_custom_not_created"
+ ]
+ },
+ {
+ "Id": "IPY-03",
+ "Description": "Implement cryptographically secure and standardized network protocols for the management, import and export of data.",
+ "Name": "Secure Interoperability and Portability Management",
+ "Attributes": [
+ {
+ "Section": "Interoperability & Portability",
+ "CCMLite": "No",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC6.7"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "IPY-04"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.1.1",
+ "5.1.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "SY1.1",
+ "SY1.2",
+ "NC1.4"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.18.1",
+ "27001: A.15.1.1",
+ "27002: 15.1.1",
+ "27017: 15.1.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.19",
+ "27001: A.5.23",
+ "27001: A.5.31",
+ "27001: A.5.32",
+ "27001: A.5.33",
+ "27001: A.5.34"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "PT-2",
+ "PT-2(2)",
+ "SA-4",
+ "SC-16",
+ "SC-16(3)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.DS-2"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.DS-02"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "1.2.1",
+ "1.2.5",
+ "1.2.6",
+ "2.2.4",
+ "2.2.5",
+ "2.2.7",
+ "4.2.1"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "storage_ensure_azure_services_are_trusted_to_access_is_enabled",
+ "storage_secure_transfer_required_is_enabled"
+ ]
+ },
+ {
+ "Id": "IVS-02",
+ "Description": "Plan and monitor the availability, quality, and adequate capacity of resources in order to deliver the required system performance as determined by the business.",
+ "Name": "Capacity and Resource Planning",
+ "Attributes": [
+ {
+ "Section": "Infrastructure & Virtualization Security",
+ "CCMLite": "No",
+ "IaaS": "CSP-Owned",
+ "PaaS": "CSP-Owned",
+ "SaaS": "CSP-Owned",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "A1.1"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "IVS-04"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "SY2.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: 5.3",
+ "27001: 6.1",
+ "27001: 9.1",
+ "27001: A.12.1.3",
+ "27002: 12.1.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: 5.3 (b)",
+ "27001: 6.1",
+ "27001: 9.1",
+ "27001: A.8.6",
+ "27001: A.8.14"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "CP-2",
+ "CP-2(2)",
+ "SC-5",
+ "SC-5(2)",
+ "SC-4",
+ "SI-4"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.DS-4",
+ "ID.BE-5"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.IR-04",
+ "GV.OC-04"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "vm_scaleset_associated_with_load_balancer",
+ "vm_scaleset_not_empty"
+ ]
+ },
+ {
+ "Id": "IVS-03",
+ "Description": "Monitor, encrypt and restrict communications between environments to only authenticated and authorized connections, as justified by the business. Review these configurations at least annually, and support them by a documented justification of all allowed services, protocols, ports, and compensating controls.",
+ "Name": "Network Security",
+ "Attributes": [
+ {
+ "Section": "Infrastructure & Virtualization Security",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "CSP-Owned",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC6.1",
+ "CC6.7"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "IVS-06"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "3.8",
+ "3.1",
+ "12.2",
+ "13.6",
+ "13.9"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.1.2",
+ "5.2.7"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "NC1.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: 7.5",
+ "27001: 9.1",
+ "27001: A.13.1.1",
+ "27002: 13.1.1",
+ "27001: A.13.1.2",
+ "27002: 13.1.2",
+ "27001: A.13.1.3",
+ "27002: 13.1.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: 7.5",
+ "27001: 9.1",
+ "27001: A.5.15",
+ "27001: A.5.37",
+ "27001: A.8.5",
+ "27001: A.8.9",
+ "27001: A.8.16",
+ "27001: A.8.20",
+ "27001: A.8.21",
+ "27001: A.8.22",
+ "27001: A.8.24",
+ "27002: A.5.15 2nd c)",
+ "27002: 8.20",
+ "27002: 8.21",
+ "27002: 8.22",
+ "27002: 8.24"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "SC-1",
+ "SC-4",
+ "SC-7",
+ "SC-7(4)",
+ "SC-7(5)",
+ "SC-7(8)",
+ "SC-7(9)",
+ "SC-7(11)",
+ "SC-8",
+ "SC-8(1)",
+ "SC-11",
+ "SC-12",
+ "SC-16",
+ "SC-23",
+ "SC-29",
+ "SC-29(1)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.AC-5",
+ "PR.AC-7",
+ "PR.PT-4",
+ "DE.CM-1",
+ "DE.CM-7",
+ "PR.DS-2"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.IR-01",
+ "PR.AA-03",
+ "PR.AA-05",
+ "DE.CM-01",
+ "PR.DS-02",
+ "ID.AM-03"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "1.1.6",
+ "1.2",
+ "1.2.3",
+ "2.2",
+ "4.1.1",
+ "10.2"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "1.2.5",
+ "1.2.6",
+ "1.2.7",
+ "1.4.2",
+ "2.2.4",
+ "2.2.5",
+ "2.2.7",
+ "4.2.1",
+ "10.1.1"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "aks_clusters_created_with_private_nodes",
+ "aks_clusters_public_access_disabled",
+ "aks_network_policy_enabled",
+ "network_bastion_host_exists",
+ "network_flow_log_captured_sent",
+ "network_flow_log_more_than_90_days",
+ "network_http_internet_access_restricted",
+ "network_rdp_internet_access_restricted",
+ "network_ssh_internet_access_restricted",
+ "network_udp_internet_access_restricted",
+ "network_watcher_enabled"
+ ]
+ },
+ {
+ "Id": "IVS-04",
+ "Description": "Harden host and guest OS, hypervisor or infrastructure control plane according to their respective best practices, and supported by technical controls, as part of a security baseline.",
+ "Name": "OS Hardening and Base Controls",
+ "Attributes": [
+ {
+ "Section": "Infrastructure & Virtualization Security",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "CSP-Owned",
+ "SaaS": "CSP-Owned",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC6.1",
+ "CC6.8",
+ "CC7.1"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "IVS-07",
+ "IVS-11"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "4.1",
+ "4.2"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "4.1.3",
+ "5.2.5"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "SY1.1",
+ "SY1.3",
+ "SY1.4"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: 7.5",
+ "27001: 9.1",
+ "27001: A.14.2.2",
+ "27002: 14.2.2",
+ "27001: A.14.2.3",
+ "27001 A.14.2.4",
+ "27018: 12.1.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: 7.5",
+ "27001: 9.1",
+ "27001: A.5.37",
+ "27001: A.8.5",
+ "27001: A.8.9",
+ "27001: A.8.16",
+ "27001: A.8.20",
+ "27001: A.8.22",
+ "27001: A.8.24",
+ "27002: 8.20",
+ "27002: 8.22",
+ "27002: 8.24"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "CM-6",
+ "CM-6(1)",
+ "SC-29",
+ "SC-29(1)",
+ "SC-2",
+ "SC-7",
+ "SC-7(12)",
+ "SC-30",
+ "SC-34",
+ "SC-35",
+ "SC-39",
+ "SC-44"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.IP-1",
+ "PR.PT-3"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.PS-01"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "2.2"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "2.2.1"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "defender_assessments_vm_endpoint_protection_installed",
+ "defender_ensure_system_updates_are_applied",
+ "vm_ensure_using_managed_disks",
+ "vm_linux_enforce_ssh_authentication",
+ "vm_trusted_launch_enabled"
+ ]
+ },
+ {
+ "Id": "IVS-06",
+ "Description": "Design, develop, deploy and configure applications and infrastructures such that CSP and CSC (tenant) user access and intra-tenant access is appropriately segmented and segregated, monitored and restricted from other tenants.",
+ "Name": "Segmentation and Segregation",
+ "Attributes": [
+ {
+ "Section": "Infrastructure & Virtualization Security",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "CSP-Owned",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "IVS-09"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "4.2.1",
+ "5.3.4",
+ "5.2.7"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "SC2.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: 9.1",
+ "27001: A.13.1.3",
+ "27002: 13.1.3",
+ "27017: 13.1.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: 9.1",
+ "27001: A.5.15",
+ "27001: A.5.20",
+ "27001: A.8.3",
+ "27001: A.8.9",
+ "27001: A.8.16",
+ "27001: A.8.22",
+ "27002: 5.15 (b)",
+ "27002: 8.3 (b)",
+ "27002: 8.16 (b)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "SC-3",
+ "SC-7",
+ "SC-7(20)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.AC-4",
+ "PR.AC-5"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.AA-05",
+ "PR.IR-01",
+ "PR.PS-01",
+ "PR.PS-06",
+ "DE.CM-09"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "2.6",
+ "8.3.1",
+ "10.8",
+ "11.3",
+ "A3.2.1",
+ "A3.3.1"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "A1.1.1",
+ "A1.1.2",
+ "A1.1.3"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "app_function_not_publicly_accessible",
+ "app_function_vnet_integration_enabled",
+ "containerregistry_uses_private_link",
+ "cosmosdb_account_use_private_endpoints",
+ "databricks_workspace_vnet_injection_enabled",
+ "network_http_internet_access_restricted",
+ "storage_ensure_private_endpoints_in_storage_accounts"
+ ]
+ },
+ {
+ "Id": "IVS-07",
+ "Description": "Use secure and encrypted communication channels when migrating servers, services, applications, or data to cloud environments. Such channels must include only up-to-date and approved protocols.",
+ "Name": "Migration to Cloud Environments",
+ "Attributes": [
+ {
+ "Section": "Infrastructure & Virtualization Security",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC6.1",
+ "CC6.7"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "IVS-10"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.1.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "IM1.4",
+ "IM1.4",
+ "NC1.4",
+ "SC2.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.13.1.1",
+ "27002: 13.1.1",
+ "27017: 13.1.1",
+ "27018: 13.1.1",
+ "27001: A.13.1.2",
+ "27002: 13.1.2",
+ "27017: 13.1.2",
+ "27018: 13.1.2",
+ "27001: A.13.1.3",
+ "27002: 13.1.3",
+ "27017: 13.1.3",
+ "27018: 13.1.3",
+ "27001: A.13.2.1",
+ "27002: 13.2.1",
+ "27017: 13.2.1",
+ "27018: 13.2.1",
+ "27001: A.13.2.2",
+ "27002: 13.2.2",
+ "27017: 13.2.2",
+ "27018: 13.2.2",
+ "27001: A.13.2.3",
+ "27002: 13.2.3",
+ "27017: 13.2.3",
+ "27018: 13.2.3",
+ "27001: A.13.2.4",
+ "27002: 13.2.4",
+ "27017: 13.2.4",
+ "27018: 13.2.4"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.14",
+ "27001: A.8.20",
+ "27001: A.8.24",
+ "27002: 8.20 (e)",
+ "27002: 8.24 Guidance (b,f), other information (a)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "AC-17",
+ "AC-20",
+ "SC-7",
+ "SC-7(28)",
+ "SC-8",
+ "SC-8(1)",
+ "SC-12",
+ "SC-23",
+ "SC-29",
+ "SI-7",
+ "SI-7(1)-(3)",
+ "SI-7(5)-(10)",
+ "SI-7(12)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.DS-2",
+ "PR.PT-4"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.DS-02"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "4.2.1"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "mysql_flexible_server_ssl_connection_enabled",
+ "postgresql_flexible_server_enforce_ssl_enabled"
+ ]
+ },
+ {
+ "Id": "IVS-09",
+ "Description": "Define, implement and evaluate processes, procedures and defense-in-depth techniques for protection, detection, and timely response to network-based attacks.",
+ "Name": "Network Defense",
+ "Attributes": [
+ {
+ "Section": "Infrastructure & Virtualization Security",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "CSP-Owned",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC6.6",
+ "CC6.8",
+ "CC7.1",
+ "CC7.2",
+ "CC7.5"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "IVS-13"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "13.3",
+ "13.8"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.2.3",
+ "5.2.4",
+ "5.2.5",
+ "5.2.7",
+ "5.3.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "NC1.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: 6.1",
+ "27001: 6.2",
+ "27001: A.14.1.2",
+ "27002: 14.1.2",
+ "27017: 14.1.2",
+ "27001: A.11.1.4",
+ "27002: 11.1.4",
+ "27017: 11.1.4",
+ "27018: 16.1.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: 6.1",
+ "27001: 6.2",
+ "27001: A.5.24",
+ "27001: A.5.26",
+ "27001: A.8.8",
+ "27001: A.8.16",
+ "27001: A.8.20",
+ "27001: A.8.21",
+ "27001: A.8.22",
+ "27001: A.8.26",
+ "27002: 8.8 (i)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "PL-8",
+ "PL-8(1)",
+ "SC-5",
+ "SC-5(1)",
+ "SC-5(3)",
+ "SC-7",
+ "SC-7(13)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "DE.AE-1",
+ "DE.DP-1",
+ "DE.CM-1",
+ "DE.CM-7",
+ "PR.AC-5",
+ "RS.MI-2",
+ "PR.DS-2",
+ "RS.RP-1"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "ID.AM-03",
+ "DE.CM-01",
+ "PR.IR-01",
+ "RS.MA-01",
+ "RS.MI-01",
+ "RS.MI-02"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "6.6",
+ "1.1",
+ "1.2",
+ "1.3",
+ "1.5",
+ "12.10.5"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "1.1.1",
+ "1.3.1",
+ "1.3.2",
+ "1.3.3",
+ "1.4.1",
+ "1.4.2",
+ "1.4.3",
+ "1.4.4",
+ "1.4.5",
+ "1.5.1",
+ "12.10.1"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "defender_ensure_defender_for_arm_is_on",
+ "defender_ensure_defender_for_dns_is_on",
+ "defender_ensure_defender_for_server_is_on",
+ "defender_ensure_iot_hub_defender_is_on",
+ "defender_ensure_wdatp_is_enabled",
+ "network_flow_log_captured_sent",
+ "network_watcher_enabled",
+ "sqlserver_microsoft_defender_enabled",
+ "vm_jit_access_enabled"
+ ]
+ },
+ {
+ "Id": "LOG-02",
+ "Description": "Define, implement and evaluate processes, procedures and technical measures to ensure the security and retention of audit logs.",
+ "Name": "Audit Logs Protection",
+ "Attributes": [
+ {
+ "Section": "Logging and Monitoring",
+ "CCMLite": "No",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "IVS-01"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "8.1",
+ "8.9",
+ "8.1"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "3.1.3",
+ "5.1.2",
+ "5.2.4"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "TM1.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.18.1.3",
+ "27002: 18.1.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.28",
+ "27001: A.5.33",
+ "27001: A.8.15"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "AU-4",
+ "AU-11"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.AC-4",
+ "PR.IP-4",
+ "PR.IP-6",
+ "PR.PT-1",
+ "PR.DS-1"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.AA-05",
+ "PR.DS-01",
+ "PR.DS-02",
+ "ID.AM-08",
+ "PR.DS-11",
+ "PR.PS-04"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "10.5",
+ "10.7"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "10.3.1",
+ "10.3.2",
+ "10.3.3",
+ "10.3.4",
+ "10.5.1"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "keyvault_logging_enabled",
+ "monitor_diagnostic_setting_with_appropriate_categories",
+ "monitor_storage_account_with_activity_logs_cmk_encrypted",
+ "monitor_storage_account_with_activity_logs_is_private",
+ "storage_ensure_encryption_with_customer_managed_keys",
+ "storage_ensure_soft_delete_is_enabled"
+ ]
+ },
+ {
+ "Id": "LOG-03",
+ "Description": "Identify and monitor security-related events within applications and the underlying infrastructure. Define and implement a system to generate alerts to responsible stakeholders based on such events and corresponding metrics.",
+ "Name": "Security Monitoring and Alerting",
+ "Attributes": [
+ {
+ "Section": "Logging and Monitoring",
+ "CCMLite": "No",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC6.8",
+ "CC7.3"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "SEF-03",
+ "SEF-05"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "8.5"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.2.4",
+ "5.2.7",
+ "1.6.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "TM1.2",
+ "TM1.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.12.4.1",
+ "27002: 12.4.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.28",
+ "27001: A.8.15"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "AU-5",
+ "AU-5(2)",
+ "AU-13"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "DE.AE-1",
+ "DE.AE-2",
+ "DE.AE-3",
+ "DE.AE-5",
+ "DE.CM-1",
+ "DE.CM-2",
+ "DE.CM-3",
+ "DE.CM-4",
+ "DE.CM-5",
+ "DE.CM-6",
+ "DE.CM-7",
+ "DE.DP-1",
+ "DE.DP-4",
+ "DE.AE-4"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.PS-04",
+ "DE.AE-02",
+ "DE.AE-03",
+ "DE.AE-04",
+ "DE.AE-06",
+ "DE.AE-07",
+ "DE.AE-08",
+ "DE.CM-01",
+ "DE.CM-02",
+ "DE.CM-03",
+ "DE.CM-06",
+ "DE.CM-09"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "10.2"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "10.2.1",
+ "10.2.2",
+ "10.4.1.1",
+ "10.4.2.1",
+ "10.4.3"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "defender_attack_path_notifications_properly_configured",
+ "defender_ensure_defender_for_app_services_is_on",
+ "defender_ensure_defender_for_azure_sql_databases_is_on",
+ "defender_ensure_defender_for_server_is_on",
+ "defender_ensure_notify_alerts_severity_is_high",
+ "defender_ensure_notify_emails_to_owners",
+ "defender_ensure_wdatp_is_enabled",
+ "monitor_alert_create_update_security_solution",
+ "monitor_alert_service_health_exists"
+ ]
+ },
+ {
+ "Id": "LOG-04",
+ "Description": "Restrict audit logs access to authorized personnel and maintain records that provide unique access accountability.",
+ "Name": "Audit Logs Access and Accountability",
+ "Attributes": [
+ {
+ "Section": "Logging and Monitoring",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "IVS-01"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "3.14"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "3.1.1",
+ "4.1.2",
+ "4.1.3",
+ "4.2.1",
+ "5.2.4"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "TM1.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.12.4.2",
+ "27001: A.12.4.1",
+ "27002: 12.4.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.33",
+ "27001: A.8.15"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "AU-9",
+ "AU-9(4)",
+ "AU-9(6)",
+ "AU-10"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.AC-1",
+ "PR.AC-4"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.AA-05",
+ "PR.PS-04"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "10.1",
+ "10.2.1",
+ "10.2.3",
+ "10.5.1",
+ "10.5.2"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "10.2.1.3",
+ "10.3.1"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "monitor_storage_account_with_activity_logs_is_private"
+ ]
+ },
+ {
+ "Id": "LOG-05",
+ "Description": "Monitor security audit logs to detect activity outside of typical or expected patterns. Establish and follow a defined process to review and take appropriate and timely actions on detected anomalies.",
+ "Name": "Audit Logs Monitoring and Response",
+ "Attributes": [
+ {
+ "Section": "Logging and Monitoring",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC7.2"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "8.8",
+ "8.11"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "1.6.1",
+ "1.6.2",
+ "5.2.4"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "TM1.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.12.4.3",
+ "27002: 12.4.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.8.15",
+ "27001: A.8.16"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "AU-6",
+ "AU-6(1)",
+ "AU-6(5)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "DE.AE-3",
+ "PR.PT-1",
+ "RS.AN-1",
+ "RS.CO-1.",
+ "DE.AE-1",
+ "DE.AE-5",
+ "DE.DP-4"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "ID.AM-03",
+ "PR.PS-04",
+ "DE.AE-02",
+ "DE.AE-03",
+ "DE.AE-06",
+ "DE.AE-07",
+ "DE.AE-08",
+ "DE.CM-01",
+ "DE.CM-02",
+ "DE.CM-03",
+ "DE.CM-06",
+ "DE.CM-09"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "10.6",
+ "10.6.1"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "10.4.1.1",
+ "10.4.2.1"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "monitor_alert_create_policy_assignment",
+ "monitor_alert_create_update_nsg",
+ "monitor_alert_create_update_public_ip_address_rule",
+ "monitor_alert_create_update_security_solution",
+ "monitor_alert_create_update_sqlserver_fr",
+ "monitor_alert_delete_nsg",
+ "monitor_alert_delete_policy_assignment",
+ "monitor_alert_delete_public_ip_address_rule",
+ "monitor_alert_delete_security_solution",
+ "monitor_alert_delete_sqlserver_fr",
+ "monitor_alert_service_health_exists"
+ ]
+ },
+ {
+ "Id": "LOG-07",
+ "Description": "Establish, document and implement which information meta/data system events should be logged. Review and update the scope at least annually or whenever there is a change in the threat environment.",
+ "Name": "Logging Scope",
+ "Attributes": [
+ {
+ "Section": "Logging and Monitoring",
+ "CCMLite": "No",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC7.2"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "8.1"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.2.4"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "TM1.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: 7.5.3",
+ "27001: A.12.4.1",
+ "27002: 12.4.1",
+ "27017: 12.4.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: 7.5.3",
+ "27001: A.8.15"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "AU-1",
+ "AU-14",
+ "AU-16"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "ID.SC-3",
+ "ID.SC-4",
+ "PR.PT-1",
+ "ID.GV-1"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.PS-04"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "10.3"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "10.2.1",
+ "10.2.2"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "app_function_application_insights_enabled",
+ "appinsights_ensure_is_configured",
+ "monitor_diagnostic_setting_with_appropriate_categories",
+ "monitor_diagnostic_settings_exists",
+ "network_flow_log_captured_sent",
+ "network_flow_log_more_than_90_days"
+ ]
+ },
+ {
+ "Id": "LOG-08",
+ "Description": "Generate audit records containing relevant security information.",
+ "Name": "Log Records",
+ "Attributes": [
+ {
+ "Section": "Logging and Monitoring",
+ "CCMLite": "No",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC7.2"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "8.2"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.2.4"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "TM1.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.12.4.1",
+ "27002: 12.4.1",
+ "27017: 12.4.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.8.15"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "AU-3",
+ "AU-3(1)",
+ "AU-3(3)",
+ "AU-6",
+ "AU-6(8)",
+ "AU-12",
+ "AU-12(1)",
+ "AU-12(2)",
+ "AU-12(3)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.PT-1",
+ "DE.AE-3",
+ "DE.CM-1",
+ "DE.CM-2",
+ "DE.CM-3",
+ "DE.CM-6",
+ "DE.CM-7"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.PS-04",
+ "DE.CM-01",
+ "DE.CM-02",
+ "DE.CM-03",
+ "DE.CM-06",
+ "DE.CM-09"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "10.3"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "10.2.2"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "app_function_application_insights_enabled",
+ "app_http_logs_enabled",
+ "appinsights_ensure_is_configured",
+ "keyvault_logging_enabled",
+ "monitor_diagnostic_setting_with_appropriate_categories",
+ "monitor_diagnostic_settings_exists",
+ "mysql_flexible_server_audit_log_connection_activated",
+ "mysql_flexible_server_audit_log_enabled",
+ "network_flow_log_captured_sent",
+ "network_flow_log_more_than_90_days",
+ "postgresql_flexible_server_log_checkpoints_on",
+ "postgresql_flexible_server_log_connections_on",
+ "postgresql_flexible_server_log_disconnections_on",
+ "postgresql_flexible_server_log_retention_days_greater_3",
+ "sqlserver_auditing_enabled",
+ "sqlserver_auditing_retention_90_days"
+ ]
+ },
+ {
+ "Id": "LOG-09",
+ "Description": "The information system protects audit records from unauthorized access, modification, and deletion.",
+ "Name": "Log Protection",
+ "Attributes": [
+ {
+ "Section": "Logging and Monitoring",
+ "CCMLite": "No",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "GRM-04",
+ "IVS-01"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.2.4",
+ "4.2.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "TM1.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.12.4.2",
+ "27002: 12.4.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.8.15"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "AU-9",
+ "AU-9(2)",
+ "AU-9(3)",
+ "AU-9(4)",
+ "AU-12(3)",
+ "AU-12(3)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.AC-4",
+ "PR.IP-4",
+ "PR.IP-6",
+ "PR.PT-1",
+ "PR.DS-1",
+ "PR.DS-6"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.AA-05",
+ "PR.DS-01",
+ "PR.DS-02",
+ "PR.DS-11"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "10.5",
+ "10.5.1",
+ "10.5.2"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "10.3.1",
+ "10.3.2",
+ "10.3.3",
+ "10.3.4"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "keyvault_logging_enabled",
+ "monitor_diagnostic_setting_with_appropriate_categories",
+ "monitor_storage_account_with_activity_logs_cmk_encrypted",
+ "monitor_storage_account_with_activity_logs_is_private",
+ "storage_ensure_encryption_with_customer_managed_keys"
+ ]
+ },
+ {
+ "Id": "LOG-10",
+ "Description": "Establish and maintain a monitoring and internal reporting capability over the operations of cryptographic, encryption and key management policies, processes, procedures, and controls.",
+ "Name": "Encryption Monitoring and Reporting",
+ "Attributes": [
+ {
+ "Section": "Logging and Monitoring",
+ "CCMLite": "No",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC6.1",
+ "CC7.2"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "EKM-02",
+ "EKM-03"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "4.2.1",
+ "5.1.1",
+ "5.1.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "TS2.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.10.1",
+ "27002: 10.1",
+ "27001: A.10.1.2",
+ "27017: 10.1.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.8.24"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "AU-1",
+ "AU-9",
+ "AU-9(3)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "ID.GV-1",
+ "PR.PT-1"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.PS-04",
+ "DE.CM-09"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "10.1.1",
+ "10.2.1",
+ "10.4.1"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "keyvault_key_expiration_set_in_non_rbac",
+ "keyvault_key_rotation_enabled",
+ "keyvault_rbac_key_expiration_set"
+ ]
+ },
+ {
+ "Id": "LOG-11",
+ "Description": "Log and monitor key lifecycle management events to enable auditing and reporting on usage of cryptographic keys.",
+ "Name": "Transaction/Activity Logging",
+ "Attributes": [
+ {
+ "Section": "Logging and Monitoring",
+ "CCMLite": "No",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC6.1",
+ "CC7.2"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "EKM-02"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.1.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "TS2.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.10.1.2",
+ "27017: 10.1.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.8.24"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "AU-9",
+ "AU-9(3)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.PT-1",
+ "DE.AE-3"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.PS-04",
+ "DE.CM-09"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "monitor_diagnostic_setting_with_appropriate_categories",
+ "monitor_diagnostic_settings_exists"
+ ]
+ },
+ {
+ "Id": "LOG-13",
+ "Description": "Define, implement and evaluate processes, procedures and technical measures for the reporting of anomalies and failures of the monitoring system and provide immediate notification to the accountable party.",
+ "Name": "Failures and Anomalies Reporting",
+ "Attributes": [
+ {
+ "Section": "Logging and Monitoring",
+ "CCMLite": "No",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC2.3",
+ "CC7.3"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "SEF-03"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "1.6.1",
+ "5.2.4"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "TM1.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.16.1.1",
+ "27002: 16.1.1",
+ "27001: A.16.1.2",
+ "27017: 16.1.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.24",
+ "27001: A.6.8",
+ "27002: 6.8 (g)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "AU-5",
+ "AU-5(2)",
+ "AU-6",
+ "AU-6(3)",
+ "AU-6(4)",
+ "AU-6(5)",
+ "AU-16"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "DE.DP-3",
+ "DE.DP-4"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.PS-04",
+ "DE.AE-06"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "10.6"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "10.4.3",
+ "10.7.1",
+ "10.7.2",
+ "10.7.3"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "defender_container_images_resolved_vulnerabilities",
+ "defender_ensure_defender_for_server_is_on",
+ "defender_ensure_notify_alerts_severity_is_high",
+ "defender_ensure_notify_emails_to_owners",
+ "defender_ensure_wdatp_is_enabled",
+ "monitor_alert_service_health_exists"
+ ]
+ },
+ {
+ "Id": "SEF-03",
+ "Description": "'Establish, document, approve, communicate, apply, evaluate and maintain a security incident response plan, which includes but is not limited to: relevant internal departments, impacted CSCs, and other business critical relationships (such as supply-chain) that may be impacted.'",
+ "Name": "Incident Response Plans",
+ "Attributes": [
+ {
+ "Section": "Security Incident Management, E-Discovery, & Cloud Forensics",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC7.2",
+ "CC7.3",
+ "CC7.4"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "BCR-02"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "17.2",
+ "17.4"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "1.6.2",
+ "1.6.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "TM2.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: 5.2",
+ "27001: 7.3",
+ "27001: 7.4",
+ "27001: 7.5",
+ "27001: A.16.1.5",
+ "27002: 16.1.5",
+ "27017: 16.1.5",
+ "27017: CLD.12.1.5",
+ "27018: 16.1.5"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: 5.2",
+ "27001: 7.3",
+ "27001: 7.4",
+ "27001: 7.5",
+ "27001: A.5.26",
+ "27002: 5.26 (e,f)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "IR-1",
+ "IR-2",
+ "IR-2(1)-(3)",
+ "IR-3",
+ "IR-3(1)-(3)",
+ "IR-4",
+ "IR-4(1)-(15)",
+ "IR-5",
+ "IR-5(1)",
+ "IR-6",
+ "IR-6(1)-(3)",
+ "IR-7",
+ "IR-7(1)",
+ "IR-7(2)",
+ "IR-8",
+ "IR-8(1)",
+ "IR-9",
+ "IR-9(1)-(4)",
+ "PM-12"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "RS.CO-1",
+ "RS.CO-4",
+ "ID.AM-6",
+ "ID.GV-2",
+ "ID.SC-5",
+ "PR.IP-9",
+ "PR.IP10"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.AT-01",
+ "PR.AT-02",
+ "RS.MA-01",
+ "GV.SC-08",
+ "ID.IM-02",
+ "ID.IM-04",
+ "RC.RP-01"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "12.1",
+ "12.10.1"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "12.10.1",
+ "12.10.5"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "defender_attack_path_notifications_properly_configured",
+ "defender_ensure_defender_for_server_is_on",
+ "defender_ensure_notify_alerts_severity_is_high"
+ ]
+ },
+ {
+ "Id": "SEF-06",
+ "Description": "Define, implement and evaluate processes, procedures and technical measures supporting business processes to triage security-related events.",
+ "Name": "Event Triage Processes",
+ "Attributes": [
+ {
+ "Section": "Security Incident Management, E-Discovery, & Cloud Forensics",
+ "CCMLite": "No",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC7.3"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "SEF-02"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "1.6.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "TM1.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.16.1.4",
+ "27002: 16.1.4",
+ "27017: 16.1.4",
+ "27018: 16.1.4",
+ "27001: A.16.1.5",
+ "27002: 16.1.5",
+ "27017: 16.1.5",
+ "27018: 16.1.5"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.25"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "CA-7",
+ "CA-7(3)",
+ "CA-7(4)",
+ "CA-7(5)",
+ "CA-7(6)",
+ "IR-4",
+ "IR-4(1)",
+ "IR-4(3)",
+ "IR-4(4)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "DE.AE-1",
+ "DE.AE-2",
+ "DE.AE-4",
+ "RS.RP-1",
+ "RS.AN-2"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "RS.MA-02",
+ "RS.MA-03",
+ "RS.AN-03",
+ "DE.AE-02",
+ "DE.AE-04",
+ "DE.AE-06",
+ "DE.AE-07",
+ "DE.AE-08",
+ "RS.MI-02",
+ "RC.RP-02"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "12.5.2"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "12.10.1"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "defender_ensure_defender_for_app_services_is_on",
+ "defender_ensure_defender_for_azure_sql_databases_is_on",
+ "defender_ensure_defender_for_databases_is_on",
+ "defender_ensure_defender_for_keyvault_is_on",
+ "defender_ensure_defender_for_server_is_on",
+ "defender_ensure_mcas_is_enabled",
+ "defender_ensure_wdatp_is_enabled"
+ ]
+ },
+ {
+ "Id": "SEF-08",
+ "Description": "Maintain points of contact for applicable regulation authorities, national and local law enforcement, and other legal jurisdictional authorities.",
+ "Name": "Points of Contact Maintenance",
+ "Attributes": [
+ {
+ "Section": "Security Incident Management, E-Discovery, & Cloud Forensics",
+ "CCMLite": "No",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC2.3"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "SEF-01"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "17.2"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "1.6.2",
+ "1.6.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "SM2.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: 4.2",
+ "27001: A.6.1.3",
+ "27002: 6.1.3",
+ "27017: 6.1.3",
+ "27018: 6.1.3",
+ "27001: A.16.1.1",
+ "27002: 16.1.1",
+ "27001: A.18.1.1",
+ "27002: 18.1.1",
+ "27017: 18.1.1",
+ "27018: 18.1.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.5",
+ "27001: A.5.24",
+ "27002: 5.24 Incident management procedure (d)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "IR-4",
+ "IR-4(8)",
+ "IR-6",
+ "IR-6(3)",
+ "IR-7",
+ "IR-7(2)",
+ "PM-21",
+ "PM-23",
+ "PM-26"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "ID.GV-2",
+ "RS.CO-3",
+ "RS.CO-4"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "GV.RR-02",
+ "RS.CO-02",
+ "RS.CO-03"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "12.10.1"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "defender_additional_email_configured_with_a_security_contact",
+ "defender_ensure_notify_emails_to_owners"
+ ]
+ },
+ {
+ "Id": "TVM-02",
+ "Description": "Establish, document, approve, communicate, apply, evaluate and maintain policies and procedures to protect against malware on managed assets. Review and update the policies and procedures at least annually.",
+ "Name": "Malware Protection Policy and Procedures",
+ "Attributes": [
+ {
+ "Section": "Threat & Vulnerability Management",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC5.3",
+ "CC6.8"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "TVM-01",
+ "GRM-06",
+ "GRM-09"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "9.7",
+ "10.1"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "1.1.1",
+ "1.5.1",
+ "5.2.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "TS1.2",
+ "TS1.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: 5.1",
+ "27001: 5.2",
+ "27001: 7.3",
+ "27001: 7.4",
+ "27001: 7.5",
+ "27001: 9.1",
+ "27001: 9.3",
+ "27001: A.5",
+ "27002: 5",
+ "27001: A.12.2.1",
+ "27001: A.6.2.1",
+ "27002: 6.2.1 (h)",
+ "27001: A.6.2.2",
+ "27002: 6.2.2 (j)",
+ "27001: A.7.2.2",
+ "27002: 7.2.2 (d)",
+ "27001: A.10.1.1",
+ "27002: 10.1.1 (g)",
+ "27001: A.13.2.1",
+ "27002: 13.2.1 (b)",
+ "27001: A.15.1.2",
+ "27017: 15.1.2",
+ "27001: A.12.2.1",
+ "27002: 12.2.1 (a),(d)",
+ "27017: CLD.9.5.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: 5.1",
+ "27001: 5.2",
+ "27001: 7.3",
+ "27001: 7.4",
+ "27001: 7.5",
+ "27001: 9.1",
+ "27001: 9.3",
+ "27001: A.5.1",
+ "27001: A.5.4",
+ "27001: A.5.7",
+ "27001: A.5.37",
+ "27001: A.8.7",
+ "27002: 5.7 (b)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "RA-3",
+ "RA-3(3)",
+ "RA-5",
+ "RA-5(3)",
+ "RA-5(5)",
+ "SI-3",
+ "SI-3(4)",
+ "SI-3(10)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "ID.GV-1",
+ "DE.CM-4",
+ "DE.CM-5"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "GV.PO-01",
+ "GV.PO-02",
+ "ID.IM-03",
+ "DE.CM-01",
+ "DE.CM-09"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "5.4",
+ "12.1",
+ "12.1.1",
+ "12.3.1",
+ "12.5.1",
+ "12.11"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "12.1.1",
+ "12.1.2",
+ "5.1.1",
+ "5.3.2.1"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "defender_assessments_vm_endpoint_protection_installed",
+ "defender_auto_provisioning_log_analytics_agent_vms_on",
+ "defender_ensure_defender_for_server_is_on",
+ "defender_ensure_wdatp_is_enabled"
+ ]
+ },
+ {
+ "Id": "TVM-03",
+ "Description": "Define, implement and evaluate processes, procedures and technical measures to enable both scheduled and emergency responses to vulnerability identifications, based on the identified risk.",
+ "Name": "Vulnerability Remediation Schedule",
+ "Attributes": [
+ {
+ "Section": "Threat & Vulnerability Management",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC5.3",
+ "CC7.1",
+ "CC7.4"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "TVM-02"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "7.2",
+ "7.7",
+ "17.9"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.2.5"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "TM1.1",
+ "TM2.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: 6.1.3",
+ "27001: A.12.2.1",
+ "27001: A.12.6.1",
+ "27002: 12.6.1(c)(d)(j)",
+ "27018: 12.6.1(k)(i)"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: 6.1.3",
+ "27001: A.8.7",
+ "27001: A.8.8",
+ "27001: A.8.32",
+ "27002: 8.7",
+ "27002: 8.8",
+ "27002: 8.32"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "PM-31",
+ "RA-3",
+ "RA-3(1)",
+ "RA-5",
+ "RA-5(2)-(4)",
+ "RA-5(6)",
+ "SI-3",
+ "SI-3(10)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "RS.AN-5",
+ "PR.IP-12"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "ID.RA-01",
+ "ID.RA-06",
+ "ID.RA-08",
+ "PR.PS-02",
+ "PR.PS-03"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "6.1",
+ "6.1.a",
+ "6.1.b"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "6.1.1",
+ "6.3.1",
+ "6.3.2",
+ "6.3.3",
+ "12.10.1"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "app_ensure_java_version_is_latest",
+ "app_ensure_php_version_is_latest",
+ "app_ensure_python_version_is_latest",
+ "app_function_latest_runtime_version",
+ "defender_ensure_system_updates_are_applied"
+ ]
+ },
+ {
+ "Id": "TVM-04",
+ "Description": "Define, implement and evaluate processes, procedures and technical measures to update detection tools, threat signatures, and indicators of compromise on a weekly, or more frequent basis.",
+ "Name": "Detection Updates",
+ "Attributes": [
+ {
+ "Section": "Threat & Vulnerability Management",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC7.2"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "No mapping"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "10.2"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.2.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "TS1.3",
+ "TS1.4",
+ "TM1.3",
+ "TM1.4",
+ "IM1.5"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: 6.1.3",
+ "27001: A.5.1.1",
+ "27002: 5.1.1 (h)",
+ "27001: A.12.6.1",
+ "27002: 12.6.1 (b),(c)"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: 6.1.3",
+ "27001: A.5.1",
+ "27001: A.8.8",
+ "27001: A.8.15",
+ "27001: A.8.16",
+ "27002: 5.1",
+ "27002: 5.37",
+ "27002: 8.8",
+ "27002: 8.15 (d)",
+ "27002: 8.16 (d,e)",
+ "27002: 8.31 2nd (a)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "CM-7",
+ "CM-7(4)",
+ "RA-3",
+ "RA-3(3)",
+ "RA-5(2)",
+ "SA-10",
+ "SA-10(5)",
+ "SA-11",
+ "SA-11(2)",
+ "SI-2",
+ "SI-2(4)",
+ "SI-3",
+ "SI-3(4)",
+ "SI-4",
+ "SI-4(9)",
+ "SI-4(24)",
+ "SI-8",
+ "SI-8(2)",
+ "SI-8(3)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "DE.DP-5",
+ "PR.IP-12"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.PS-02",
+ "ID.RA-02"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "5.2",
+ "5.2a",
+ "5.2b",
+ "5.2c"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "5.3.1"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "defender_auto_provisioning_vulnerabilty_assessments_machines_on",
+ "defender_container_images_scan_enabled",
+ "defender_ensure_defender_for_containers_is_on",
+ "defender_ensure_defender_for_cosmosdb_is_on",
+ "defender_ensure_defender_for_os_relational_databases_is_on",
+ "defender_ensure_defender_for_server_is_on",
+ "defender_ensure_defender_for_sql_servers_is_on",
+ "defender_ensure_wdatp_is_enabled"
+ ]
+ },
+ {
+ "Id": "TVM-05",
+ "Description": "Define, implement and evaluate processes, procedures and technical measures to identify updates for applications which use third party or open source libraries according to the organization's vulnerability management policy.",
+ "Name": "External Library Vulnerabilities",
+ "Attributes": [
+ {
+ "Section": "Threat & Vulnerability Management",
+ "CCMLite": "No",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "CSP-Owned",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC3.2"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "No mapping"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "2.6"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "TM1.1",
+ "SD2.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: 6.1.3",
+ "27001: A.12.6.2",
+ "27002: 12.6.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: 6.1.3",
+ "27001: A 5.6",
+ "27001: A.8.19",
+ "27001: A.8.8",
+ "27001: A.8.28",
+ "27001: A.8.31",
+ "27002: 5.6 (c)",
+ "27001: 8.19",
+ "27001: 8.8",
+ "27001: 8.28",
+ "27001: 8.31"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "RA-5",
+ "RA-5(3)",
+ "SA-11",
+ "SA-11(2)",
+ "SA-11(5)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "DE.DP-5",
+ "PR.IP-12"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "ID.RA-01",
+ "ID.RA-03",
+ "PR.PS-02"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "6.1",
+ "6.2",
+ "6.3.2"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "6.3.1",
+ "6.3.2",
+ "6.3.3"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "defender_container_images_resolved_vulnerabilities",
+ "defender_container_images_scan_enabled",
+ "defender_ensure_defender_for_containers_is_on",
+ "sqlserver_va_emails_notifications_admins_enabled",
+ "sqlserver_va_periodic_recurring_scans_enabled",
+ "sqlserver_va_scan_reports_configured",
+ "sqlserver_vulnerability_assessment_enabled"
+ ]
+ },
+ {
+ "Id": "TVM-07",
+ "Description": "Define, implement and evaluate processes, procedures and technical measures for the detection of vulnerabilities on organizationally managed assets at least monthly.",
+ "Name": "Vulnerability Identification",
+ "Attributes": [
+ {
+ "Section": "Threat & Vulnerability Management",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC7.1"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "TVM-02"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "7.1",
+ "7.5",
+ "7.6"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.2.5",
+ "5.2.6"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "TM1.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.12.6",
+ "27001: A.12.6.1",
+ "27002: 12.6.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.8.8",
+ "27002: 8.8"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "RA-5",
+ "RA-5(4)",
+ "RA-5(5)",
+ "SA-11",
+ "SA-11(5)",
+ "SA-15(5)",
+ "SC-7",
+ "SC-7(10)",
+ "SI-3(8)",
+ "SI-3(10)",
+ "SI-7",
+ "SI-7(9)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "ID.RA-1",
+ "DE.CM-8",
+ "PR.IP-12"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "ID.RA-01"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "6.1",
+ "11.2",
+ "11.2.1"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "6.3.1",
+ "6.3.2",
+ "6.3.3",
+ "11.3.2",
+ "11.3.2.1"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "defender_auto_provisioning_vulnerabilty_assessments_machines_on",
+ "defender_container_images_resolved_vulnerabilities",
+ "defender_container_images_scan_enabled",
+ "defender_ensure_defender_for_containers_is_on",
+ "defender_ensure_defender_for_server_is_on",
+ "defender_ensure_wdatp_is_enabled",
+ "sqlserver_microsoft_defender_enabled",
+ "sqlserver_vulnerability_assessment_enabled"
+ ]
+ },
+ {
+ "Id": "UEM-08",
+ "Description": "Protect information from unauthorized disclosure on managed endpoint devices with storage encryption.",
+ "Name": "Storage Encryption",
+ "Attributes": [
+ {
+ "Section": "Universal Endpoint Management",
+ "CCMLite": "No",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC6.1",
+ "CC6.7"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "MOS-11"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "3.6"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.1.2",
+ "3.1.4"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "PA1.2",
+ "PA1.3",
+ "PA1.5",
+ "PA2.2",
+ "PM1.4"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.11.2.7",
+ "27002: 11.2.7",
+ "27001: A.18.1.1",
+ "27017: 18.1.1",
+ "27001: A.12.3.1",
+ "27017: 12.3.1",
+ "27018: A.11.4",
+ "27018: A.11.5"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.8.1",
+ "27002: 8.1 (h)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "AC-19(5)",
+ "SC-28",
+ "SC-28(1)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.DS-1"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.DS-01"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "3.4",
+ "3.6"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "3.5.1",
+ "3.6"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "databricks_workspace_cmk_encryption_enabled",
+ "storage_infrastructure_encryption_is_enabled",
+ "vm_ensure_attached_disks_encrypted_with_cmk",
+ "vm_ensure_unattached_disks_encrypted_with_cmk"
+ ]
+ },
+ {
+ "Id": "UEM-11",
+ "Description": "Configure managed endpoints with Data Loss Prevention (DLP) technologies and rules in accordance with a risk assessment.",
+ "Name": "Data Loss Prevention",
+ "Attributes": [
+ {
+ "Section": "Universal Endpoint Management",
+ "CCMLite": "No",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC6.7"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "3.13"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.2.7"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "IM1.5",
+ "PA2.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.12.3",
+ "27002: 12.3",
+ "27001: A.8.3.1",
+ "27002: 8.3.1",
+ "27001: A.12.2",
+ "27002: 12.2",
+ "27001: A.18.1.3",
+ "27002: 18.1.3",
+ "27001: A.6.1.1",
+ "27017: 6.1.1",
+ "27018: 12.3.1",
+ "27018: 10.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.12",
+ "27001: A.8.3"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "SC-7",
+ "SC-7(10)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.DS-5"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.DS-02",
+ "PR.DS-10",
+ "PR.PS-01",
+ "ID.AM-08",
+ "DE.CM-09"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "A3.2.6"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "A3.2.6"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "defender_ensure_defender_for_storage_is_on",
+ "defender_ensure_mcas_is_enabled"
+ ]
+ }
+ ]
+}
diff --git a/prowler/compliance/gcp/csa_ccm_4.0_gcp.json b/prowler/compliance/gcp/csa_ccm_4.0_gcp.json
new file mode 100644
index 0000000000..6623fe5eca
--- /dev/null
+++ b/prowler/compliance/gcp/csa_ccm_4.0_gcp.json
@@ -0,0 +1,7386 @@
+{
+ "Framework": "CSA-CCM",
+ "Name": "CSA Cloud Controls Matrix (CCM) v4.0.13",
+ "Version": "4.0",
+ "Provider": "GCP",
+ "Description": "The Cloud Security Alliance (CSA) Cloud Controls Matrix (CCM) is a cybersecurity control framework for cloud computing, composed of 197 control objectives structured in 17 domains covering all key aspects of cloud technology. The CCM can be used as a tool for the systematic assessment of a cloud implementation, and provides guidance on which security controls should be implemented by which actor within the cloud supply chain.",
+ "Requirements": [
+ {
+ "Id": "A&A-02",
+ "Description": "Conduct independent audit and assurance assessments according to relevant standards at least annually.",
+ "Name": "Independent Assessments",
+ "Attributes": [
+ {
+ "Section": "Audit & Assurance",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC4.1"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "AAC-02"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "1.5.2",
+ "5.2.6"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "AS1.1",
+ "AS2.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.18.2.1",
+ "27002: 18.2.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.35",
+ "27001: A.5.36"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "CA-2",
+ "CA-2(1)",
+ "CA-2(2)",
+ "CA-7",
+ "CA-7(1)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "ID.IM-01"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "iam_audit_logs_enabled"
+ ]
+ },
+ {
+ "Id": "A&A-04",
+ "Description": "Verify compliance with all relevant standards, regulations, legal/contractual, and statutory requirements applicable to the audit.",
+ "Name": "Requirements Compliance",
+ "Attributes": [
+ {
+ "Section": "Audit & Assurance",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC3.1"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "GRM-01",
+ "GRM-03"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "7.1.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "AS1.1",
+ "AS2.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: 9.3.2",
+ "27001: A.18.2.2",
+ "27002: 18.2.2",
+ "27001: A.18.2.3",
+ "27002: 18.2.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: 9.3.2",
+ "27001: A.5.31",
+ "27001: A.5.32",
+ "27001: A.5.33",
+ "27001: A.5.34",
+ "27001: A.5.36"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "CA-1"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "ID.GV-3",
+ "DE.DP-2"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "ID.IM-01"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "iam_audit_logs_enabled",
+ "iam_cloud_asset_inventory_enabled"
+ ]
+ },
+ {
+ "Id": "AIS-04",
+ "Description": "Define and implement a SDLC process for application design, development, deployment, and operation in accordance with security requirements defined by the organization.",
+ "Name": "Secure Application Design and Development",
+ "Attributes": [
+ {
+ "Section": "Application & Interface Security",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "CSP-Owned",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC6.8",
+ "CC8.1"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "AIS-01",
+ "AIS-03"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "16.1"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "1.3.4",
+ "5.3.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "SD1.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.14.1.1",
+ "27002: 14.1.1",
+ "27017: 14.1.1",
+ "27001: A.14.1.2",
+ "27002: 14.1.2",
+ "27017: 14.1.2",
+ "27001: A.14.2.1",
+ "27002: 14.2.1",
+ "27017: 14.2.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.8",
+ "27001: A.8.25",
+ "27001: A.8.26",
+ "27001: A.8.28"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "PL-2",
+ "PL-8",
+ "PL-8(1)",
+ "SA-3",
+ "SA-3(1)",
+ "SA-4",
+ "SA-4(2)",
+ "SA-4(3)",
+ "SA-4(8)",
+ "SA-4(9)",
+ "SA-5",
+ "SA-8",
+ "SA-8(1)-(7)",
+ "SA-8(9)-(13)",
+ "SA-8(15)-(20)",
+ "SA-8(22)",
+ "SA-8(24)-(28)",
+ "SA-8(30)-(33)",
+ "SA-17",
+ "SA-17(1)-(9)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.DS-6",
+ "PR.DS-7",
+ "PR.IP-2"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "ID.AM-08",
+ "PR.IR-01",
+ "PR.PS-01",
+ "PR.PS-02",
+ "PR.PS-06"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "6.3"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "6.2.1",
+ "6.2.3",
+ "6.5.2"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": []
+ },
+ {
+ "Id": "AIS-05",
+ "Description": "Implement a testing strategy, including criteria for acceptance of new information systems, upgrades and new versions, which provides application security assurance and maintains compliance while enabling organizational speed of delivery goals. Automate when applicable and possible.",
+ "Name": "Automated Application Security Testing",
+ "Attributes": [
+ {
+ "Section": "Application & Interface Security",
+ "CCMLite": "No",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC6.8",
+ "CC8.1"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "AIS-01",
+ "AIS-03"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "16.12",
+ "16.13"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "SD2.3",
+ "SD2.5"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.14.2.8",
+ "27001: A.14.2.9",
+ "27001: A.12.1.2",
+ "27002: 12.1.2",
+ "27001: A.14.1.1",
+ "27002: 14.1.1",
+ "27001: A.14.2.2",
+ "27002: 14.2.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.8.25",
+ "27001: A.8.29",
+ "27001: A.8.32",
+ "27002: 8.25 (e)",
+ "27002: 8.32 (d)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "SA-11",
+ "SA-11(1)-(9)",
+ "SI-6",
+ "SI-6(2)",
+ "SI-6(3)",
+ "SI-10",
+ "SI-10(1)-(6)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.IP-2",
+ "PR.PT-3",
+ "PR.IP-12",
+ "DE.CM-8"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "ID.AM-08",
+ "ID.RA-01",
+ "PR.PS-01",
+ "PR.PS-02"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "A.3.2.2",
+ "A.3.2.2.1",
+ "6.6"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "6.2.4",
+ "6.4.1",
+ "6.4.2",
+ "6.5.1"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "gcr_container_scanning_enabled",
+ "artifacts_container_analysis_enabled"
+ ]
+ },
+ {
+ "Id": "AIS-07",
+ "Description": "Define and implement a process to remediate application security vulnerabilities, automating remediation when possible.",
+ "Name": "Application Vulnerability Remediation",
+ "Attributes": [
+ {
+ "Section": "Application & Interface Security",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC7.1",
+ "CC7.4",
+ "CC8.1"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "TVM-02"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "16.2",
+ "16.6"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "TM1.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.16.1.5",
+ "27002: 16.1.5",
+ "27017: 16.1.5",
+ "27001: A.12.6.1",
+ "27002: 12.6.1",
+ "27017: 12.6.1",
+ "27018: 12.6.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.26",
+ "27001: A.8.8",
+ "27002: 5.26 (j)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "SI-2",
+ "SI-2(2)-(6)",
+ "SA-11",
+ "SA-11(2)",
+ "SA-15",
+ "SA-15(1)-(3)",
+ "SA-15(5)-(8)",
+ "SA-15(10)-(12)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.IP-2",
+ "PR.IP-12",
+ "DE.CM-8",
+ "RS.AN-5",
+ "RS.MI-3",
+ "PR.DS-6"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "ID.AM-08",
+ "ID.RA-01",
+ "ID.RA-06",
+ "ID.RA-08",
+ "PR.PS-02",
+ "PR.PS-06"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "6.2",
+ "6.5",
+ "6.5.1-10"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "6.3.1",
+ "11.3.1",
+ "11.3.1.1"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "gcr_container_scanning_enabled",
+ "artifacts_container_analysis_enabled"
+ ]
+ },
+ {
+ "Id": "BCR-08",
+ "Description": "Periodically backup data stored in the cloud. Ensure the confidentiality, integrity and availability of the backup, and verify data restoration from backup for resiliency.",
+ "Name": "Backup",
+ "Attributes": [
+ {
+ "Section": "Business Continuity Management and Operational Resilience",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "A1.2",
+ "A1.3"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "BCR-11"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "11.1",
+ "11.2",
+ "11.3",
+ "11.4",
+ "11.5"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.2.8",
+ "5.2.9"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "SY2.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.12.3",
+ "27017: 12.3",
+ "27018: 12.3.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.8.13",
+ "27001: A.5.23",
+ "27001: A.5.30",
+ "27002: 8.13",
+ "27002: 5.23 2nd (i)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "CP-4",
+ "CP-4(4)",
+ "CP-6",
+ "CP-6(1)-(3)",
+ "CP-9",
+ "CP-9(1)",
+ "CP-9(2)",
+ "CP-10",
+ "CP-10(2)",
+ "CP-10(4)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.IP-4",
+ "PR.DS-1"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.DS-01",
+ "PR.DS-11",
+ "RC.RP-03"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "9.5.1",
+ "12.10.1"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "12.10.1",
+ "10.3.3"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "cloudsql_instance_automated_backups",
+ "cloudstorage_bucket_versioning_enabled",
+ "cloudstorage_bucket_soft_delete_enabled"
+ ]
+ },
+ {
+ "Id": "BCR-09",
+ "Description": "Establish, document, approve, communicate, apply, evaluate and maintain a disaster response plan to recover from natural and man-made disasters. Update the plan at least annually or upon significant changes.",
+ "Name": "Disaster Response Plan",
+ "Attributes": [
+ {
+ "Section": "Business Continuity Management and Operational Resilience",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "A1.2",
+ "CC3.2"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.2.8",
+ "5.2.9",
+ "1.6.1",
+ "1.6.2",
+ "1.6.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "BC1.4",
+ "BC2.1",
+ "BC2.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.29",
+ "27001: A.5.30",
+ "27002: 5.29",
+ "27002: 5.30"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "CP-2(1)",
+ "CP-2(2)",
+ "CP-2(3)",
+ "CP-2(5)",
+ "CP-2(6)",
+ "CP-2(7)",
+ "CP-2(8)",
+ "PE-13",
+ "PE-13(1)",
+ "PE-13(2)",
+ "PE-13(4)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.IP-9",
+ "PR.IP-10",
+ "RC.IM-1",
+ "RC.IM-2"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "ID.IM-04"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": []
+ },
+ {
+ "Id": "BCR-11",
+ "Description": "Supplement business-critical equipment with redundant equipment independently located at a reasonable minimum distance in accordance with applicable industry standards.",
+ "Name": "Equipment Redundancy",
+ "Attributes": [
+ {
+ "Section": "Business Continuity Management and Operational Resilience",
+ "CCMLite": "No",
+ "IaaS": "CSP-Owned",
+ "PaaS": "CSP-Owned",
+ "SaaS": "CSP-Owned",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "A1.2",
+ "CC3.2"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "BCR-06"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.2.8"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "BC1.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.20",
+ "27001: A.7.11",
+ "27001: A.8.14",
+ "27002: 5.20 (t)",
+ "27002: 8.14 (c)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "CP-2",
+ "CP-2(2)",
+ "CP-4(3)",
+ "CP-6",
+ "CP-6(1)",
+ "CP-7",
+ "CP-8",
+ "CP-8(1)-(3)",
+ "CP-9",
+ "CP-9(6)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "ID.BE-4",
+ "ID.BE-5"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "GV.OC-04",
+ "GV.OC-05",
+ "PR.IR-03"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "compute_instance_automatic_restart_enabled",
+ "compute_instance_group_autohealing_enabled",
+ "compute_instance_group_load_balancer_attached",
+ "compute_instance_group_multiple_zones",
+ "compute_instance_on_host_maintenance_migrate"
+ ]
+ },
+ {
+ "Id": "CCC-04",
+ "Description": "Restrict the unauthorized addition, removal, update, and management of organization assets.",
+ "Name": "Unauthorized Change Protection",
+ "Attributes": [
+ {
+ "Section": "Change Control and Configuration Management",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC8.1"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "CCC-04"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.2.1",
+ "1.3.4",
+ "5.3.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "SY2.4",
+ "SM2.6"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.12.1.4",
+ "27002: 12.1.4",
+ "27001: A.12.4.2",
+ "27002: 12.4.2",
+ "27001: A.14.2.2",
+ "27017: 14.2.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.8.3",
+ "27001: A.8.4",
+ "27001: A.8.15",
+ "27001: A.8.31",
+ "27001: A.8.32"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "CA-7",
+ "CA-7(4)",
+ "CM-3",
+ "CM-3(1)",
+ "CM-3(5)",
+ "CM-3(7)",
+ "CM-3(8)",
+ "CM-5",
+ "CM-5(1)",
+ "CM-5(4)",
+ "CM-5(5)",
+ "CM-6",
+ "CM-6(1)",
+ "CM-6(2)",
+ "CM-7",
+ "CM-7(1)",
+ "CM-7(4)",
+ "CM-7(5)",
+ "CM-7(9)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "ID.AM-1",
+ "ID.AM-2",
+ "ID.AM-4",
+ "PR.MA-1",
+ "PR.MA-2",
+ "PR.AC-1"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "ID.AM-01",
+ "ID.AM-02",
+ "ID.AM-04",
+ "ID.AM-08",
+ "PR.PS-02",
+ "PR.PS-03",
+ "PR.PS-05",
+ "PR.AA-05"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "6.4.5.2"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "6.5.1",
+ "6.5.2"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "cloudstorage_bucket_log_retention_policy_lock",
+ "iam_audit_logs_enabled",
+ "logging_log_metric_filter_and_alert_for_custom_role_changes_enabled",
+ "logging_log_metric_filter_and_alert_for_project_ownership_changes_enabled"
+ ]
+ },
+ {
+ "Id": "CCC-07",
+ "Description": "Implement detection measures with proactive notification in case of changes deviating from the established baseline.",
+ "Name": "Detection of Baseline Deviation",
+ "Attributes": [
+ {
+ "Section": "Change Control and Configuration Management",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC8.1"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "GRM-01"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "1.5.1",
+ "1.5.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "SY2.4"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.14.2.2",
+ "27001: A.14.2.4",
+ "27001: A.12.4.1",
+ "27002: 12.4.1 (g)",
+ "27001: A.5.1.1",
+ "27017: 5.1.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.8.9",
+ "27001: A.8.15",
+ "27002: 8.9"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "CM-6",
+ "CM-6(2)",
+ "SI-2",
+ "SI-2(2)-(6)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.MA-1",
+ "PR.IP-1",
+ "DE.DP-4",
+ "PR.IP-3"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.PS-01",
+ "DE.CM-09",
+ "DE.AE-06"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "6.4.5.3",
+ "6.4.5.4",
+ "11.5",
+ "11.5.1"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "11.5.2",
+ "11.6.1"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "logging_log_metric_filter_and_alert_for_audit_configuration_changes_enabled",
+ "logging_log_metric_filter_and_alert_for_bucket_permission_changes_enabled",
+ "logging_log_metric_filter_and_alert_for_compute_configuration_changes_enabled",
+ "logging_log_metric_filter_and_alert_for_custom_role_changes_enabled",
+ "logging_log_metric_filter_and_alert_for_project_ownership_changes_enabled",
+ "logging_log_metric_filter_and_alert_for_sql_instance_configuration_changes_enabled",
+ "logging_log_metric_filter_and_alert_for_vpc_firewall_rule_changes_enabled",
+ "logging_log_metric_filter_and_alert_for_vpc_network_changes_enabled",
+ "logging_log_metric_filter_and_alert_for_vpc_network_route_changes_enabled"
+ ]
+ },
+ {
+ "Id": "CEK-03",
+ "Description": "Provide cryptographic protection to data at-rest and in-transit, using cryptographic libraries certified to approved standards.",
+ "Name": "Data Encryption",
+ "Attributes": [
+ {
+ "Section": "Cryptography, Encryption & Key Management",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC6.1",
+ "CC6.7"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "EKM-03",
+ "EKM-04"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "3.6",
+ "3.1",
+ "3.11",
+ "11.3",
+ "16.11"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.1.1",
+ "5.1.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "TS2.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.18.1.1",
+ "27001: A.18.1.2",
+ "27001: A.18.1.3",
+ "27001: A.18.1.4",
+ "27001: A.18.1.5",
+ "27001: A.10.1",
+ "27002: 10.1",
+ "27001: A.13.2.1",
+ "27002: 13.2.1",
+ "27001: A.18",
+ "27002: 18",
+ "27001: A.14.1.2",
+ "27002: 14.1.2",
+ "27001: A.14.1.3",
+ "27002 14.1.3 c)",
+ "27001 - A.10.1.1",
+ "27017 - 10.1.1",
+ "27001 - A.10.1.2",
+ "27017 - 10.1.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.14",
+ "27001: A.8.24",
+ "27002: 8.24 Other Information (a)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "AC-19",
+ "AC-19(5)",
+ "SC-8",
+ "SC-8(1)",
+ "SC-8(3)",
+ "SC-8(4)",
+ "SC-12",
+ "SC-12(2)",
+ "SC-12(3)",
+ "SC-28",
+ "SC-28(1)-(3)",
+ "SI-4",
+ "SI-4(10)",
+ "SI-7",
+ "SI-7(6)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.DS-1",
+ "PR.DS-2"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.DS-01",
+ "PR.DS-02"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "Requirement 3",
+ "2.2.3",
+ "2.3",
+ "3.4",
+ "3.5.3",
+ "4.1",
+ "8.2.1",
+ "PCI Glossary - Strong Cryptography"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "2.2.7",
+ "3.5.1",
+ "4.2.1",
+ "4.2.1.2",
+ "4.2.2"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "compute_instance_encryption_with_csek_enabled",
+ "compute_instance_confidential_computing_enabled",
+ "bigquery_dataset_cmk_encryption",
+ "bigquery_table_cmk_encryption",
+ "cloudsql_instance_ssl_connections",
+ "dataproc_encrypted_with_cmks_disabled"
+ ]
+ },
+ {
+ "Id": "CEK-04",
+ "Description": "Use encryption algorithms that are appropriate for data protection, considering the classification of data, associated risks, and usability of the encryption technology.",
+ "Name": "Encryption Algorithm",
+ "Attributes": [
+ {
+ "Section": "Cryptography, Encryption & Key Management",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC6.1",
+ "CC6.7"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "EKM-04"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "16.11"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.1.1",
+ "5.1.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "TS2.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: 6.1.2",
+ "27001: 6.1.3",
+ "27001: A.8.2",
+ "27002: 8.2",
+ "27001: A.8.3",
+ "27001: A.10.1.1",
+ "27002: 10.1.1 (b)",
+ "27001: A.10.1.2",
+ "27002: 10.1.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: 6.1.2",
+ "27001: 6.1.3",
+ "27001: A.8.24",
+ "27001: A.5.12",
+ "27001: A.5.13",
+ "27002: 8.24 General (b)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "SC-12",
+ "SC-12(2)",
+ "SC-12(3)",
+ "SC-28",
+ "SC-28(1)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.DS-1",
+ "PR.DS-2",
+ "ID.AM-5"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.DS-01",
+ "PR.DS-02",
+ "ID.AM-05"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "A2",
+ "Requirement 3",
+ "2.3",
+ "2.2.3",
+ "3.4",
+ "3.5.3",
+ "4.1",
+ "8.2.1",
+ "PCI Glossary - Strong Cryptography"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "2.2.7",
+ "3.5.1",
+ "4.2.1",
+ "4.2.1.2",
+ "4.2.2"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "dns_rsasha1_in_use_to_key_sign_in_dnssec",
+ "dns_rsasha1_in_use_to_zone_sign_in_dnssec"
+ ]
+ },
+ {
+ "Id": "CEK-08",
+ "Description": "CSPs must provide the capability for CSCs to manage their own data encryption keys.",
+ "Name": "CSC Key Management Capability",
+ "Attributes": [
+ {
+ "Section": "Cryptography, Encryption & Key Management",
+ "CCMLite": "No",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "TS2.2",
+ "SC2.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.10.1",
+ "27017: 10.1",
+ "27001: A.10.1.1",
+ "27017: 10.1.1",
+ "27001: A.10.1.2",
+ "27017: 10.1.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.23",
+ "27001: A.8.24"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "CP-9",
+ "CP-9(8)",
+ "SA-9",
+ "SA-9(6)",
+ "SC-12",
+ "SC-12(6)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "ID.SC-3",
+ "ID.AM-6",
+ "PR.AC-1"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "GV.SC-05"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "bigquery_dataset_cmk_encryption",
+ "bigquery_table_cmk_encryption",
+ "compute_instance_encryption_with_csek_enabled",
+ "dataproc_encrypted_with_cmks_disabled",
+ "kms_key_not_publicly_accessible",
+ "kms_key_rotation_enabled"
+ ]
+ },
+ {
+ "Id": "CEK-10",
+ "Description": "Generate Cryptographic keys using industry accepted cryptographic libraries specifying the algorithm strength and the random number generator used.",
+ "Name": "Key Generation",
+ "Attributes": [
+ {
+ "Section": "Cryptography, Encryption & Key Management",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "EKM-04"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "16.11"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.1.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "TS2.2",
+ "TS2.3",
+ "SY1.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.10.1.1",
+ "27002: 10.1.1 (e)",
+ "27017: 10.1.1",
+ "27001: A.10.1.2",
+ "27002: 10.1.2",
+ "27002: 10.1.2 (a)",
+ "27017: 10.1.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.8.24",
+ "27002: 8.24 (d), Key management (a)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "SC-12",
+ "SC-12(2)",
+ "SC-12(3)",
+ "SC-13"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.AC-1"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.AA-01",
+ "PR.AA-05"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "2.2.3",
+ "3.6.1",
+ "PCI Glossary - Cryptographic Key Generation"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "3.6.1",
+ "3.6.1.1",
+ "3.7.1"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "bigquery_dataset_cmk_encryption",
+ "bigquery_table_cmk_encryption",
+ "dataproc_encrypted_with_cmks_disabled"
+ ]
+ },
+ {
+ "Id": "CEK-12",
+ "Description": "Rotate cryptographic keys in accordance with the calculated cryptoperiod, which includes provisions for considering the risk of information disclosure and legal and regulatory requirements.",
+ "Name": "Key Rotation",
+ "Attributes": [
+ {
+ "Section": "Cryptography, Encryption & Key Management",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.1.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "TS2.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.10.1.1",
+ "27017: 10.1.1",
+ "27001: A.10.1.2",
+ "27002: 10.1.2 e)",
+ "27017: 10.1.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.31",
+ "27001: A.8.24",
+ "27002: 5.31 Cryptography",
+ "27002: 8.24 Key management (e,m)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "SC-12",
+ "SC-12(2)",
+ "SC-12(3)",
+ "SC-13"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.AC-1",
+ "ID.GV-3"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.AA-01",
+ "PR.AA-05",
+ "GV.OC-03"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "3.7.4",
+ "3.7.5"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "kms_key_rotation_enabled",
+ "iam_sa_user_managed_key_rotate_90_days",
+ "apikeys_key_rotated_in_90_days"
+ ]
+ },
+ {
+ "Id": "CEK-14",
+ "Description": "Define, implement and evaluate processes, procedures and technical measures to destroy keys stored outside a secure environment and revoke keys stored in Hardware Security Modules (HSMs) when they are no longer needed, which include provisions for legal and regulatory requirements.",
+ "Name": "Key Destruction",
+ "Attributes": [
+ {
+ "Section": "Cryptography, Encryption & Key Management",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.1.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "TS2.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.10.1.1",
+ "27017: 10.1.1",
+ "27017: 10.1.2",
+ "27001: A.10.1.2",
+ "27002: 10.1.2 (j)",
+ "27001: A.18.1.3",
+ "27002: 18.1.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.31",
+ "27001: A.8.24",
+ "27002: 5.31 Cryptography",
+ "27002: 8.24 Key management (j,m)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "SC-12",
+ "SC-12(2)",
+ "SC-12(3)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.AC-1",
+ "PR.IP-6",
+ "ID.GV-3",
+ "PR.DS-3"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.AA-01",
+ "PR.AA-05",
+ "ID.AM-08",
+ "GV.OC-03"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "3.6.4",
+ "3.6.5"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "3.7.4",
+ "3.7.5"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "iam_role_kms_enforce_separation_of_duties"
+ ]
+ },
+ {
+ "Id": "DCS-06",
+ "Description": "Catalogue and track all relevant physical and logical assets located at all of the CSP's sites within a secured system.",
+ "Name": "Assets Cataloguing and Tracking",
+ "Attributes": [
+ {
+ "Section": "Datacenter Security",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC6.1"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "DCS - 01"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "1.1",
+ "2.1"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "1.3.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "SM2.6"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.8.1.1",
+ "27002: 8.1.1",
+ "27017: 8.1.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.9"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "CM-8",
+ "CM-8(1)",
+ "CM-8(2)",
+ "CM-8(4)",
+ "CM-8(7)",
+ "CM-8(8)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "ID.AM-1",
+ "ID.AM-2",
+ "ID.AM-4",
+ "PR.AC-4"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "ID.AM-01",
+ "ID.AM-02",
+ "ID.AM-04"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "2.4",
+ "9.7.1",
+ "9.9.1",
+ "9.9.1.a",
+ "9.9.1.b",
+ "9.9.1.c",
+ "12.3.3",
+ "12.3.4"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "3.6.1.1",
+ "6.3.2",
+ "9.4.2",
+ "9.4.3",
+ "12.5.1"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "iam_cloud_asset_inventory_enabled"
+ ]
+ },
+ {
+ "Id": "DSP-02",
+ "Description": "Apply industry accepted methods for the secure disposal of data from storage media such that data is not recoverable by any forensic means.",
+ "Name": "Secure Disposal",
+ "Attributes": [
+ {
+ "Section": "Data Security and Privacy Lifecycle Management",
+ "CCMLite": "No",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC6.1",
+ "CC6.2",
+ "CC6.3",
+ "CC6.4",
+ "CC6.5",
+ "CC6.7",
+ "P4.3"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "DSI-07"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "3.5"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.1.1",
+ "5.3.3",
+ "7.1.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "IM1.1",
+ "IM1.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.8.3.2",
+ "27002: 8.3.2",
+ "27001: A.11.2.7",
+ "27002: 11.2.7"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.7.10",
+ "27001: A.7.14",
+ "27001: A.8.10",
+ "27002: 7.10 (Secure reuse or disposal)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "PM-22",
+ "SI-12",
+ "SI-12(3)",
+ "SI-18",
+ "SI-18(1)",
+ "SI-18(4)",
+ "SI-18(5)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.IP-6"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "GV.SC-10",
+ "PR.PS-02",
+ "PR.PS-03",
+ "ID.AM-08"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "3.1",
+ "9.8",
+ "9.8.1",
+ "9.8.2"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "3.2.1",
+ "3.7.5",
+ "9.4.7"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "cloudstorage_bucket_lifecycle_management_enabled"
+ ]
+ },
+ {
+ "Id": "DSP-03",
+ "Description": "Create and maintain a data inventory, at least for any sensitive data and personal data.",
+ "Name": "Data Inventory",
+ "Attributes": [
+ {
+ "Section": "Data Security and Privacy Lifecycle Management",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC6.1"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "3.2"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "1.3.1",
+ "1.3.2",
+ "1.3.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "IM1.1",
+ "IM2.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.8.1.1",
+ "27002: 8.1.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.9",
+ "27001: A.8.12"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "CM-12",
+ "CM-12(1)",
+ "PM-5",
+ "PM-5(1)",
+ "SI-12",
+ "SI-12(1)",
+ "SI-19",
+ "SI-19(1)",
+ "SI-19(2)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "ID.AM-5"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "ID.AM-07"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "3.2.1",
+ "9.4.5"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "iam_cloud_asset_inventory_enabled",
+ "iam_audit_logs_enabled"
+ ]
+ },
+ {
+ "Id": "DSP-04",
+ "Description": "Classify data according to its type and sensitivity level.",
+ "Name": "Data Classification",
+ "Attributes": [
+ {
+ "Section": "Data Security and Privacy Lifecycle Management",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC6.1",
+ "C1.1"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "DSI-01"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "3.7"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "1.3.1",
+ "1.3.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "IM1.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.8.2.1",
+ "27002: 8.2.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.12"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "AC-16",
+ "AC-16(9)",
+ "PM-22",
+ "PM-23",
+ "PT-2",
+ "PT-2(1)",
+ "SI-18",
+ "SI-18(2)",
+ "SI-19",
+ "SI-19(6)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "ID.AM-5"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "ID.AM-05",
+ "ID.AM-07"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "9.6.1"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "9.4.2",
+ "9.4.3"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": []
+ },
+ {
+ "Id": "DSP-07",
+ "Description": "Develop systems, products, and business practices based upon a principle of security by design and industry best practices.",
+ "Name": "Data Protection by Design and Default",
+ "Attributes": [
+ {
+ "Section": "Data Security and Privacy Lifecycle Management",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "PI1.2",
+ "PI1.3"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "16.1"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.3.1",
+ "5.3.2",
+ "5.3.3",
+ "5.3.4"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "SD2.2",
+ "IM1.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.14.1.1",
+ "27002:14.1.1",
+ "27001: A.14.2.5",
+ "27002:14.2.5"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.8.27",
+ "27001: A.8.28",
+ "27001: A.8.29",
+ "27002: 5.8 (Information security requirements a-i)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "PM-17",
+ "PM-24",
+ "PM-25",
+ "PT-2",
+ "PT-2(2)",
+ "SA-3",
+ "SA-4",
+ "SA-5",
+ "SA-8",
+ "SA-8(9)",
+ "SA-8(13)",
+ "SA-8(18)",
+ "SA-8(20)",
+ "SA-8(22)",
+ "SA-8(23)",
+ "SA-8(33)",
+ "SA-15",
+ "SA-15(12)",
+ "SC-3",
+ "SC-3(3)",
+ "SC-7",
+ "SC-7(24)",
+ "SC-8",
+ "SC-8(1)-(4)",
+ "SC-28",
+ "SC-28(1)",
+ "SI-12",
+ "SI-12(1)-(3)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.IP-2",
+ "PR.PT-3",
+ "PR.AC-4"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "ID.AM-08",
+ "PR.PS-06"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "6.2.1"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "bigquery_dataset_public_access",
+ "cloudsql_instance_public_access",
+ "cloudsql_instance_public_ip",
+ "cloudstorage_bucket_public_access",
+ "compute_image_not_publicly_shared",
+ "compute_instance_public_ip",
+ "kms_key_not_publicly_accessible"
+ ]
+ },
+ {
+ "Id": "DSP-10",
+ "Description": "Define, implement and evaluate processes, procedures and technical measures that ensure any transfer of personal or sensitive data is protected from unauthorized access and only processed within scope as permitted by the respective laws and regulations.",
+ "Name": "Sensitive Data Transfer",
+ "Attributes": [
+ {
+ "Section": "Data Security and Privacy Lifecycle Management",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC6.7"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "GRM-02",
+ "EKM-03"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "3.1",
+ "3.12",
+ "3.13"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.1.2",
+ "9.5.1",
+ "9.5.2",
+ "9.5.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "IM1.4",
+ "IM2.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.13.2.1",
+ "27002: 13.2.1",
+ "27001: A.8.3.3",
+ "27002: 8.3.3",
+ "27001: A.13.2.3",
+ "27002: 13.2.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.14",
+ "27001: A.7.10"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "AC-4",
+ "AC-4(23)-(25)",
+ "CA-3",
+ "CA-3(6)",
+ "CA-6",
+ "CA-6(1)",
+ "CA-6(2)",
+ "SC-4",
+ "SC-4(2)",
+ "SC-7",
+ "SC-7(10)",
+ "SC-7(24)",
+ "SC-8",
+ "SC-8(1)-(5)",
+ "SC-16",
+ "SC-16(1)-(3)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.DS-2",
+ "PR.DS-5",
+ "PR.PT-4"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.DS-02",
+ "PR.IR-01",
+ "ID.AM-03",
+ "GV.OC-03",
+ "ID.AM-07"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "4.1"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "4.1.1",
+ "4.2.1",
+ "4.2.2"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "cloudsql_instance_ssl_connections"
+ ]
+ },
+ {
+ "Id": "DSP-16",
+ "Description": "Data retention, archiving and deletion is managed in accordance with business requirements, applicable laws and regulations.",
+ "Name": "Data Retention and Deletion",
+ "Attributes": [
+ {
+ "Section": "Data Security and Privacy Lifecycle Management",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "C1.1",
+ "C1.2",
+ "CC3.1",
+ "P4.2"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "GRM-02",
+ "BCR-11"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "3.4",
+ "3.5"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.1.1",
+ "5.3.1",
+ "7.1.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "IM1.1",
+ "IM2.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.18.1.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.33",
+ "27001: A.8.10",
+ "27002: 5.33 (b)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "SI-12",
+ "SI-12(1)-(3)",
+ "SI-18",
+ "SI-18(1)",
+ "SI-18(4)",
+ "SI-18(5)",
+ "SI-19",
+ "SI-19(2)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.DS-3",
+ "PR.IP-6",
+ "ID.GV-3"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "ID.AM-08",
+ "GV.OC-03",
+ "GV.SC-10",
+ "PR.DS-11"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "3.1"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "3.2.1"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "cloudstorage_bucket_lifecycle_management_enabled",
+ "cloudstorage_bucket_sufficient_retention_period"
+ ]
+ },
+ {
+ "Id": "DSP-17",
+ "Description": "Define and implement, processes, procedures and technical measures to protect sensitive data throughout it's lifecycle.",
+ "Name": "Sensitive Data Protection",
+ "Attributes": [
+ {
+ "Section": "Data Security and Privacy Lifecycle Management",
+ "CCMLite": "Yes",
+ "IaaS": "CSP-Owned",
+ "PaaS": "CSP-Owned",
+ "SaaS": "CSC-Owned",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC2.1",
+ "CC6.1",
+ "CC6.3",
+ "CC6.7",
+ "CC8.1",
+ "C1.1",
+ "P2.0",
+ "P3.0",
+ "P4.0",
+ "P5.0",
+ "P6.0"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "3.1",
+ "3.1",
+ "3.14"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.3.3",
+ "9.1.1",
+ "9.2.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "IM1.1",
+ "IM2.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.18.1.3",
+ "27002: 18.1.3",
+ "27001:A.18.1.4",
+ "27002:18.1.4"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.8.11",
+ "27001: A.8.12"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "PL-2",
+ "PM-22",
+ "PM-24",
+ "PT-7",
+ "PT-7(1)",
+ "PT-7(2)",
+ "PT-8",
+ "SC-8",
+ "SC-8(1)-(5)",
+ "SC-28",
+ "SC-28(1)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.DS-1",
+ "PR.DS-2",
+ "PR.DS-5"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.DS-01",
+ "PR.DS-02",
+ "PR.DS-10"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "3.0 (including all subsections)",
+ "4.0 (including all subsections)"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "3.1.1",
+ "4.1.1"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "cloudstorage_bucket_public_access",
+ "bigquery_dataset_public_access",
+ "cloudsql_instance_public_access",
+ "cloudsql_instance_public_ip",
+ "compute_instance_public_ip",
+ "compute_image_not_publicly_shared",
+ "kms_key_not_publicly_accessible"
+ ]
+ },
+ {
+ "Id": "GRC-05",
+ "Description": "Develop and implement an Information Security Program, which includes programs for all the relevant domains of the CCM.",
+ "Name": "Information Security Program",
+ "Attributes": [
+ {
+ "Section": "Governance, Risk and Compliance",
+ "CCMLite": "No",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "GRM-04"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "14.1"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "1.2.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "SG2.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: 4.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: 4.3"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "PM-1",
+ "PM-3",
+ "PM-14",
+ "PL-2",
+ "PM-18",
+ "PM-31"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "12.4.1",
+ "A.3.1"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "12.4.1",
+ "A3.1.1"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "iam_account_access_approval_enabled",
+ "iam_audit_logs_enabled",
+ "iam_organization_essential_contacts_configured"
+ ]
+ },
+ {
+ "Id": "IAM-02",
+ "Description": "Establish, document, approve, communicate, implement, apply, evaluate and maintain strong password policies and procedures. Review and update the policies and procedures at least annually.",
+ "Name": "Strong Password Policy and Procedures",
+ "Attributes": [
+ {
+ "Section": "Identity & Access Management",
+ "CCMLite": "No",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "IAM-02",
+ "IAM-12",
+ "GRM-06",
+ "GRM-09"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "5.2"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "1.1.1",
+ "1.5.1",
+ "4.1.2",
+ "4.1.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "SA1.1",
+ "SA1.5"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: 5.1",
+ "27001: 5.2",
+ "27001: 7.3",
+ "27001: 7.4",
+ "27001: 7.5",
+ "27001: 9.1",
+ "27001: 9.3",
+ "27001: A.5",
+ "27002: 5",
+ "27001: A.9.4.3",
+ "27002: 9.4.3",
+ "27017: 9.4.3",
+ "27018: 9.4.3",
+ "27001: A.9.2.4",
+ "27002: 9.2.4",
+ "27017: 9.2.4",
+ "27001: A.7.2.2",
+ "27002: 7.2.2",
+ "27001: A.9.2.6",
+ "27002: 9.2.6",
+ "27001: A.9.2.3",
+ "27002: 9.2.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: 5.1",
+ "27001: 5.2",
+ "27001: 7.3",
+ "27001: 7.4",
+ "27001: 7.5",
+ "27001: 9.1",
+ "27001: 9.3",
+ "27001: A.5.1",
+ "27001: A.5.4",
+ "27001: A.5.17",
+ "27001: A.6.3",
+ "27001: A.8.5",
+ "27001: A.5.37"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "AC-2",
+ "AC-2(3)",
+ "AC-2(11)",
+ "AC-3",
+ "AC-3(3)",
+ "AC-12",
+ "AC-12(1)",
+ "IA-2",
+ "IA-2(10)",
+ "IA-5",
+ "IA-5(1)",
+ "IA-5(18)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "ID.GV-1",
+ "PR.AC-1",
+ "PR.AC-7"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "GV.PO-01",
+ "GV.PO-02",
+ "ID.IM-03",
+ "PR.AA-03"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "8.4",
+ "12.1",
+ "12.1.1",
+ "12.11"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "8.1.1",
+ "8.3.8"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": []
+ },
+ {
+ "Id": "IAM-03",
+ "Description": "Manage, store, and review the information of system identities, and level of access.",
+ "Name": "Identity Inventory",
+ "Attributes": [
+ {
+ "Section": "Identity & Access Management",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC6.1",
+ "CC6.3"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "IAM-04",
+ "IAM-08",
+ "IAM-10"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "5.1",
+ "5.2"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "4.1.3",
+ "4.2.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "SA1.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: 9.2 (c)",
+ "27001: A.8.1.1",
+ "27002: 8.1.1",
+ "27001: A.9.4.1",
+ "27002: 9.4.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: 9.2 (c)",
+ "27001: A.5.15",
+ "27001: A.5.16",
+ "27001: A.5.18",
+ "27001: A.7.4",
+ "27001: A.8.15",
+ "27001: A.8.2",
+ "27001: A.8.3"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "AU-10",
+ "AU-10(1)",
+ "AU-10(2)",
+ "AU-16",
+ "AU-16(1)",
+ "IA-4",
+ "IA-4(8)",
+ "IA-4(9)",
+ "IA-5",
+ "IA-5(5)",
+ "IA-8",
+ "IA-8(4)",
+ "PM-5(1)",
+ "SA-8",
+ "SA-8(22)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.AC-1",
+ "PR.AC-6",
+ "PR.AC-4"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.AA-01",
+ "PR.AA-02",
+ "PR.AA-04",
+ "PR.AA-05"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "2.4.a"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "7.2.5",
+ "7.2.5.1"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "iam_sa_user_managed_key_unused",
+ "iam_service_account_unused"
+ ]
+ },
+ {
+ "Id": "IAM-04",
+ "Description": "Employ the separation of duties principle when implementing information system access.",
+ "Name": "Separation of Duties",
+ "Attributes": [
+ {
+ "Section": "Identity & Access Management",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC1.3",
+ "CC5.1",
+ "CC6.3"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "IAM-05"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "6.8"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "1.2.2",
+ "4.2.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "SA1.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.6.1.2",
+ "27002: 6.1.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.15",
+ "27001: A.5.18",
+ "27001: A.5.3",
+ "27001: A.8.2"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "AC-2",
+ "AC-2(3)",
+ "AC-2(11)",
+ "AC-6",
+ "AC-6(1)-(10)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.AC-4"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.AA-05"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "6.4",
+ "6.4.2"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "6.5.3",
+ "6.5.4",
+ "7.2.1",
+ "7.2.2"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "iam_role_sa_enforce_separation_of_duties",
+ "iam_role_kms_enforce_separation_of_duties",
+ "iam_no_service_roles_at_project_level"
+ ]
+ },
+ {
+ "Id": "IAM-05",
+ "Description": "Employ the least privilege principle when implementing information system access.",
+ "Name": "Least Privilege",
+ "Attributes": [
+ {
+ "Section": "Identity & Access Management",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC6.3"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "IAM-02",
+ "IAM-06",
+ "IVS-11"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "6.8"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "4.2.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "SA1.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.9.1.1",
+ "27002: 9.1.1",
+ "27001: A.9.1.2",
+ "27002: 9.1.2",
+ "27001: A.9.2.3",
+ "27002: 9.2.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.15",
+ "27001: A.8.2",
+ "27002: 5.15 (Other information 2nd (a))"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "AC-6",
+ "AC-6(4)",
+ "IA-12",
+ "IA-12(2)",
+ "IA-12(3)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.AC-4"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.AA-05"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "7.1",
+ "7.1.1",
+ "7.1.2"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "7.2.1",
+ "7.2.2",
+ "7.2.5",
+ "7.2.6"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "apikeys_api_restrictions_configured",
+ "compute_instance_default_service_account_in_use",
+ "compute_instance_default_service_account_in_use_with_full_api_access",
+ "gke_cluster_no_default_service_account",
+ "iam_no_service_roles_at_project_level",
+ "iam_sa_no_administrative_privileges"
+ ]
+ },
+ {
+ "Id": "IAM-07",
+ "Description": "De-provision or respectively modify access of movers / leavers or system identity changes in a timely manner in order to effectively adopt and communicate identity and access management policies.",
+ "Name": "User Access Changes and Revocation",
+ "Attributes": [
+ {
+ "Section": "Identity & Access Management",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC5.3",
+ "CC6.3"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "IAM-11"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "5.3",
+ "6.2"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "4.2.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "SA1.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.15",
+ "27001: A.5.18"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "AC-2",
+ "AC-2(1)",
+ "AC-2(2)",
+ "AC-2(6)",
+ "AC-2(8)",
+ "AC-3",
+ "AC-3(8)",
+ "AC-6",
+ "AC-6(7)",
+ "AU-10",
+ "AU-10(4)",
+ "AU-16",
+ "AU-16(1)",
+ "CM-7",
+ "CM-7(1)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.AC-1",
+ "PR.AC-4",
+ "PR.IP-11"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "GV.RR-04",
+ "GV.SC-10",
+ "PR.AA-01",
+ "PR.AA-05"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "8.1.2",
+ "8.1.3"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "8.2.5",
+ "8.2.6"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "iam_sa_user_managed_key_unused",
+ "iam_service_account_unused"
+ ]
+ },
+ {
+ "Id": "IAM-08",
+ "Description": "Review and revalidate user access for least privilege and separation of duties with a frequency that is commensurate with organizational risk tolerance.",
+ "Name": "User Access Review",
+ "Attributes": [
+ {
+ "Section": "Identity & Access Management",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC6.2",
+ "CC6.3"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "IAM-10"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "5.1"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "4.2.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "SA1.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.9.2.5",
+ "27001: A.9.2.6",
+ "27001: A.9.4.1",
+ "27017: 9.4.1",
+ "27001: A.6.1.2",
+ "27001: A 9.2.5"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.3",
+ "27001: A.5.18",
+ "27001: A.8.3"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "AC-6",
+ "AC-6(4)",
+ "AC-6(8)",
+ "IA-8",
+ "IA-8(4)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.AC-4"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.AA-05"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "12.5.5"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "7.2.5.1",
+ "7.2.5",
+ "7.2.4"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "iam_sa_user_managed_key_unused",
+ "iam_service_account_unused",
+ "iam_sa_user_managed_key_rotate_90_days"
+ ]
+ },
+ {
+ "Id": "IAM-09",
+ "Description": "Define, implement and evaluate processes, procedures and technical measures for the segregation of privileged access roles such that administrative access to data, encryption and key management capabilities and logging capabilities are distinct and separated.",
+ "Name": "Segregation of Privileged Access Roles",
+ "Attributes": [
+ {
+ "Section": "Identity & Access Management",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC5.1",
+ "CC6.1",
+ "CC6.3"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "5.4"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "SA1.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.9.2.3",
+ "27002: 9.2.3",
+ "27017: 9.2.3",
+ "27018: 9.2.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.8.2",
+ "27001: A.8.18",
+ "27002: 8.2 (j)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "AC-6",
+ "AC-3(7)",
+ "AC-6(4)",
+ "AC-6(8)",
+ "IA-5",
+ "IA-5(6)",
+ "IA-8",
+ "IA-8(4)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.AC-1",
+ "PR.AC-4"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.AA-01",
+ "PR.AA-05"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "2.3",
+ "3.5.2",
+ "7.1.2",
+ "7.1.1"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "3.6.1",
+ "3.7.6",
+ "6.5.3",
+ "6.5.4",
+ "7.2.1",
+ "7.2.2",
+ "10.3.1"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "iam_role_kms_enforce_separation_of_duties",
+ "iam_role_sa_enforce_separation_of_duties",
+ "iam_sa_no_administrative_privileges"
+ ]
+ },
+ {
+ "Id": "IAM-10",
+ "Description": "Define and implement an access process to ensure privileged access roles and rights are granted for a time limited period, and implement procedures to prevent the culmination of segregated privileged access.",
+ "Name": "Management of Privileged Access Roles",
+ "Attributes": [
+ {
+ "Section": "Identity & Access Management",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC6.1",
+ "CC6.2",
+ "CC6.3"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "5.1",
+ "6.5"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "SA1.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.9.2.3",
+ "27002: 9.2.3",
+ "27017: 9.2.3",
+ "27018: 9.2.3",
+ "27001: A.9.4.4",
+ "27002: 9.4.4",
+ "27017: 9.4.4"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.8.2",
+ "27001: A.8.18",
+ "27002: 8.2 (i)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "AC-2",
+ "AC-2(7)",
+ "AC-3",
+ "AC-3(4)",
+ "AC-3(11)",
+ "AC-3(13)",
+ "AC-3(14)",
+ "AC-6",
+ "AC-6(4)",
+ "AC-6(5)",
+ "AC-6(8)",
+ "AC-12",
+ "AC-12(3)",
+ "AC-17",
+ "AC-17(4)",
+ "IA-8",
+ "IA-8(4)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.AC-4"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.AA-05"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "7.1"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "7.2.1",
+ "7.2.2"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "iam_no_service_roles_at_project_level",
+ "iam_role_kms_enforce_separation_of_duties",
+ "iam_role_sa_enforce_separation_of_duties",
+ "iam_sa_no_administrative_privileges"
+ ]
+ },
+ {
+ "Id": "IAM-12",
+ "Description": "Define, implement and evaluate processes, procedures and technical measures to ensure the logging infrastructure is read-only for all with write access, including privileged access roles, and that the ability to disable it is controlled through a procedure that ensures the segregation of duties and break glass procedures.",
+ "Name": "Safeguard Logs Integrity",
+ "Attributes": [
+ {
+ "Section": "Identity & Access Management",
+ "CCMLite": "No",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "3.3"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "4.2.1",
+ "5.2.4"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "TM1.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.12.4.1",
+ "27002: 12.4.1",
+ "27017: 12.4.1",
+ "27018: 12.4.1",
+ "27001: A.12.4.2",
+ "27002: 12.4.2",
+ "27017: 12.4.2",
+ "27018: 12.4.2",
+ "27001: A.12.4.3",
+ "27002: 12.4.3",
+ "27017: 12.4.3",
+ "27018: 12.4.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.8.15",
+ "27001: A.8.18",
+ "27002: 8.15 Protection of Logs"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "AC-2",
+ "AC-2(11)",
+ "AC-2(12)",
+ "IA-8",
+ "IA-8(4)",
+ "SA-8",
+ "SA-8(22)",
+ "SC-34",
+ "SC-34(1)",
+ "SC-34(2)",
+ "SC-36",
+ "SI-4",
+ "SI-4(5)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.AC-4"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.AA-05"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "10.5"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "10.3.1",
+ "10.3.2",
+ "10.3.3",
+ "10.3.4"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "cloudstorage_bucket_log_retention_policy_lock",
+ "cloudstorage_bucket_logging_enabled",
+ "logging_sink_created"
+ ]
+ },
+ {
+ "Id": "IAM-13",
+ "Description": "Define, implement and evaluate processes, procedures and technical measures that ensure users are identifiable through unique IDs or which can associate individuals to the usage of user IDs.",
+ "Name": "Uniquely Identifiable Users",
+ "Attributes": [
+ {
+ "Section": "Identity & Access Management",
+ "CCMLite": "No",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC6.1"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "4.1.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "SA1.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.9.2.1",
+ "27002: 9.2.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.16"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "AC-3",
+ "AC-3(14)",
+ "AC-24",
+ "AC-24(2)",
+ "AU-10",
+ "AU-10(1)",
+ "IA-2",
+ "IA-2(1)",
+ "IA-2(2)",
+ "IA-2(12)",
+ "IA-4",
+ "IA-4(1)",
+ "SA-8",
+ "SA-8(22)",
+ "SC-23",
+ "SC-23(3)",
+ "SC-40(4)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.AC-1",
+ "PR.AC-6"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.AA-01",
+ "PR.AA-02"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "8.1",
+ "8.2",
+ "8.6"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "8.2.1",
+ "8.2.2",
+ "8.2.4"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "compute_project_os_login_enabled"
+ ]
+ },
+ {
+ "Id": "IAM-14",
+ "Description": "Define, implement and evaluate processes, procedures and technical measures for authenticating access to systems, application and data assets, including multifactor authentication for at least privileged user and sensitive data access. Adopt digital certificates or alternatives which achieve an equivalent level of security for system identities.",
+ "Name": "Strong Authentication",
+ "Attributes": [
+ {
+ "Section": "Identity & Access Management",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC6.1",
+ "CC6.2"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "IAM-02",
+ "IAM-05"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "6.3",
+ "6.5",
+ "12.5",
+ "12.7"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "4.1.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "SA1.3",
+ "SA1.4",
+ "SA1.8"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.9.1.2",
+ "27002: 9.1.2",
+ "27017: 9.1.2",
+ "27001: A.9.2.4",
+ "27002: 9.2.4",
+ "27017: 9.2.4",
+ "27001: A.9.4.2",
+ "27002: 9.4.2",
+ "27017: 9.4.2",
+ "27018: 9.4.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.15",
+ "27001: A.5.17",
+ "27001: A.8.5",
+ "27001: A.8.24",
+ "27002: 8.5",
+ "27002: 8.24 other information (d)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "AC-6",
+ "AC-6(5)",
+ "AC-7",
+ "AC-7(4)",
+ "AU-10",
+ "AU-10(2)",
+ "IA-2",
+ "IA-2(1)",
+ "IA-2(2)",
+ "IA-2(8)",
+ "IA-2(12)",
+ "IA-3",
+ "IA-3(1)",
+ "IA-5",
+ "IA-5(2)",
+ "IA-5(7)",
+ "IA-5(9)",
+ "IA-5(10)",
+ "IA-5(12)",
+ "IA-5(14)-(16)",
+ "IA-8",
+ "IA-8(1)",
+ "IA-8(6)",
+ "SC-23",
+ "SC-23(3)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.AC-1",
+ "PR.AC-6",
+ "PR.AC-7"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.AA-01",
+ "PR.AA-02",
+ "PR.AA-03"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "8.1.2",
+ "8.1.3",
+ "8.1.6",
+ "8.2",
+ "8.3",
+ "8.3.2",
+ "12.3.2"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "7.2.1",
+ "8.3.1",
+ "8.3.2",
+ "8.4.1",
+ "8.4.2",
+ "8.4.3"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "compute_project_os_login_2fa_enabled",
+ "compute_project_os_login_enabled"
+ ]
+ },
+ {
+ "Id": "IAM-15",
+ "Description": "Define, implement and evaluate processes, procedures and technical measures for the secure management of passwords.",
+ "Name": "Passwords Management",
+ "Attributes": [
+ {
+ "Section": "Identity & Access Management",
+ "CCMLite": "No",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC6.1",
+ "CC6.2"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "4.1.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "SA1.5"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.9.2.4",
+ "27002: 9.2.4",
+ "27017: 9.2.4",
+ "27018: 9.2.4",
+ "27001: A.9.3.1",
+ "27002: 9.3.1",
+ "27017: 9.3.1",
+ "27018: 9.3.1",
+ "27001: A.9.4.3",
+ "27002: 9.4.3",
+ "27017: 9.4.3",
+ "27018: 9.4.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.17"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "IA-4",
+ "IA-4(8)",
+ "IA-5",
+ "IA-5(1)",
+ "IA-5(8)",
+ "IA-5(18)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.AC-1"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.AA-01"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "8.2",
+ "8.2.1-6"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "2.2.2",
+ "2.3.1",
+ "8.3.5",
+ "8.3.6",
+ "8.3.7",
+ "8.3.8",
+ "8.3.9",
+ "8.3.10",
+ "8.3.10.1",
+ "8.6.2"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": []
+ },
+ {
+ "Id": "IAM-16",
+ "Description": "Define, implement and evaluate processes, procedures and technical measures to verify access to data and system functions is authorized.",
+ "Name": "Authorization Mechanisms",
+ "Attributes": [
+ {
+ "Section": "Identity & Access Management",
+ "CCMLite": "No",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC6.1",
+ "CC6.2",
+ "CC6.3"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "IAM-02"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "5.1"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "4.2.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "SA1.3",
+ "SA1.4"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.9.2.5",
+ "27002: 9.2.5",
+ "27017: 9.2.5",
+ "27018: 9.2.5"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.18"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "AC-3",
+ "AC-3(5)",
+ "AC-4",
+ "AC-4(17)",
+ "AC-4(21)",
+ "AC-4(22)",
+ "AC-6",
+ "AC-6(8)",
+ "AC-6(9)",
+ "AC-12",
+ "AC-12(1)",
+ "AC-20",
+ "AC-20(1)",
+ "AU-10",
+ "AU-10(1)",
+ "AU-10(2)",
+ "IA-2",
+ "IA-2(1)",
+ "IA-2(2)",
+ "IA-2(12)",
+ "IA-3",
+ "IA-3(1)",
+ "IA-5(1)",
+ "IA-5(2)",
+ "IA-5(5)",
+ "IA-5(8)",
+ "IA-5(10)",
+ "IA-5(12)",
+ "IA-8",
+ "IA-8(1)",
+ "IA-8(2)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.AC-1",
+ "PR.AC-4",
+ "PR.AC-6",
+ "PR.AC-7",
+ "PR.PT-1"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.AA-01",
+ "PR.AA-02",
+ "PR.AA-03",
+ "PR.AA-04",
+ "PR.AA-05",
+ "PR.PS-04"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "5.3",
+ "7.1.4"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "7.2.4",
+ "7.2.3",
+ "7.2.5.1"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "apikeys_api_restrictions_configured",
+ "cloudstorage_bucket_uniform_bucket_level_access",
+ "compute_instance_default_service_account_in_use_with_full_api_access",
+ "iam_sa_no_administrative_privileges"
+ ]
+ },
+ {
+ "Id": "IPY-03",
+ "Description": "Implement cryptographically secure and standardized network protocols for the management, import and export of data.",
+ "Name": "Secure Interoperability and Portability Management",
+ "Attributes": [
+ {
+ "Section": "Interoperability & Portability",
+ "CCMLite": "No",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC6.7"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "IPY-04"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.1.1",
+ "5.1.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "SY1.1",
+ "SY1.2",
+ "NC1.4"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.18.1",
+ "27001: A.15.1.1",
+ "27002: 15.1.1",
+ "27017: 15.1.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.19",
+ "27001: A.5.23",
+ "27001: A.5.31",
+ "27001: A.5.32",
+ "27001: A.5.33",
+ "27001: A.5.34"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "PT-2",
+ "PT-2(2)",
+ "SA-4",
+ "SC-16",
+ "SC-16(3)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.DS-2"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.DS-02"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "1.2.1",
+ "1.2.5",
+ "1.2.6",
+ "2.2.4",
+ "2.2.5",
+ "2.2.7",
+ "4.2.1"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "cloudsql_instance_ssl_connections"
+ ]
+ },
+ {
+ "Id": "IVS-02",
+ "Description": "Plan and monitor the availability, quality, and adequate capacity of resources in order to deliver the required system performance as determined by the business.",
+ "Name": "Capacity and Resource Planning",
+ "Attributes": [
+ {
+ "Section": "Infrastructure & Virtualization Security",
+ "CCMLite": "No",
+ "IaaS": "CSP-Owned",
+ "PaaS": "CSP-Owned",
+ "SaaS": "CSP-Owned",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "A1.1"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "IVS-04"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "SY2.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: 5.3",
+ "27001: 6.1",
+ "27001: 9.1",
+ "27001: A.12.1.3",
+ "27002: 12.1.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: 5.3 (b)",
+ "27001: 6.1",
+ "27001: 9.1",
+ "27001: A.8.6",
+ "27001: A.8.14"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "CP-2",
+ "CP-2(2)",
+ "SC-5",
+ "SC-5(2)",
+ "SC-4",
+ "SI-4"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.DS-4",
+ "ID.BE-5"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.IR-04",
+ "GV.OC-04"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "compute_instance_group_autohealing_enabled",
+ "compute_instance_group_load_balancer_attached",
+ "compute_instance_group_multiple_zones"
+ ]
+ },
+ {
+ "Id": "IVS-03",
+ "Description": "Monitor, encrypt and restrict communications between environments to only authenticated and authorized connections, as justified by the business. Review these configurations at least annually, and support them by a documented justification of all allowed services, protocols, ports, and compensating controls.",
+ "Name": "Network Security",
+ "Attributes": [
+ {
+ "Section": "Infrastructure & Virtualization Security",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "CSP-Owned",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC6.1",
+ "CC6.7"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "IVS-06"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "3.8",
+ "3.1",
+ "12.2",
+ "13.6",
+ "13.9"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.1.2",
+ "5.2.7"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "NC1.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: 7.5",
+ "27001: 9.1",
+ "27001: A.13.1.1",
+ "27002: 13.1.1",
+ "27001: A.13.1.2",
+ "27002: 13.1.2",
+ "27001: A.13.1.3",
+ "27002: 13.1.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: 7.5",
+ "27001: 9.1",
+ "27001: A.5.15",
+ "27001: A.5.37",
+ "27001: A.8.5",
+ "27001: A.8.9",
+ "27001: A.8.16",
+ "27001: A.8.20",
+ "27001: A.8.21",
+ "27001: A.8.22",
+ "27001: A.8.24",
+ "27002: A.5.15 2nd c)",
+ "27002: 8.20",
+ "27002: 8.21",
+ "27002: 8.22",
+ "27002: 8.24"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "SC-1",
+ "SC-4",
+ "SC-7",
+ "SC-7(4)",
+ "SC-7(5)",
+ "SC-7(8)",
+ "SC-7(9)",
+ "SC-7(11)",
+ "SC-8",
+ "SC-8(1)",
+ "SC-11",
+ "SC-12",
+ "SC-16",
+ "SC-23",
+ "SC-29",
+ "SC-29(1)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.AC-5",
+ "PR.AC-7",
+ "PR.PT-4",
+ "DE.CM-1",
+ "DE.CM-7",
+ "PR.DS-2"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.IR-01",
+ "PR.AA-03",
+ "PR.AA-05",
+ "DE.CM-01",
+ "PR.DS-02",
+ "ID.AM-03"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "1.1.6",
+ "1.2",
+ "1.2.3",
+ "2.2",
+ "4.1.1",
+ "10.2"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "1.2.5",
+ "1.2.6",
+ "1.2.7",
+ "1.4.2",
+ "2.2.4",
+ "2.2.5",
+ "2.2.7",
+ "4.2.1",
+ "10.1.1"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "compute_firewall_rdp_access_from_the_internet_allowed",
+ "compute_firewall_ssh_access_from_the_internet_allowed",
+ "compute_instance_ip_forwarding_is_enabled",
+ "compute_network_default_in_use",
+ "compute_network_dns_logging_enabled",
+ "compute_network_not_legacy",
+ "compute_subnet_flow_logs_enabled"
+ ]
+ },
+ {
+ "Id": "IVS-04",
+ "Description": "Harden host and guest OS, hypervisor or infrastructure control plane according to their respective best practices, and supported by technical controls, as part of a security baseline.",
+ "Name": "OS Hardening and Base Controls",
+ "Attributes": [
+ {
+ "Section": "Infrastructure & Virtualization Security",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "CSP-Owned",
+ "SaaS": "CSP-Owned",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC6.1",
+ "CC6.8",
+ "CC7.1"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "IVS-07",
+ "IVS-11"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "4.1",
+ "4.2"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "4.1.3",
+ "5.2.5"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "SY1.1",
+ "SY1.3",
+ "SY1.4"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: 7.5",
+ "27001: 9.1",
+ "27001: A.14.2.2",
+ "27002: 14.2.2",
+ "27001: A.14.2.3",
+ "27001 A.14.2.4",
+ "27018: 12.1.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: 7.5",
+ "27001: 9.1",
+ "27001: A.5.37",
+ "27001: A.8.5",
+ "27001: A.8.9",
+ "27001: A.8.16",
+ "27001: A.8.20",
+ "27001: A.8.22",
+ "27001: A.8.24",
+ "27002: 8.20",
+ "27002: 8.22",
+ "27002: 8.24"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "CM-6",
+ "CM-6(1)",
+ "SC-29",
+ "SC-29(1)",
+ "SC-2",
+ "SC-7",
+ "SC-7(12)",
+ "SC-30",
+ "SC-34",
+ "SC-35",
+ "SC-39",
+ "SC-44"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.IP-1",
+ "PR.PT-3"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.PS-01"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "2.2"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "2.2.1"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "compute_instance_shielded_vm_enabled",
+ "compute_project_os_login_enabled",
+ "compute_instance_serial_ports_in_use",
+ "compute_instance_block_project_wide_ssh_keys_disabled"
+ ]
+ },
+ {
+ "Id": "IVS-06",
+ "Description": "Design, develop, deploy and configure applications and infrastructures such that CSP and CSC (tenant) user access and intra-tenant access is appropriately segmented and segregated, monitored and restricted from other tenants.",
+ "Name": "Segmentation and Segregation",
+ "Attributes": [
+ {
+ "Section": "Infrastructure & Virtualization Security",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "CSP-Owned",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "IVS-09"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "4.2.1",
+ "5.3.4",
+ "5.2.7"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "SC2.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: 9.1",
+ "27001: A.13.1.3",
+ "27002: 13.1.3",
+ "27017: 13.1.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: 9.1",
+ "27001: A.5.15",
+ "27001: A.5.20",
+ "27001: A.8.3",
+ "27001: A.8.9",
+ "27001: A.8.16",
+ "27001: A.8.22",
+ "27002: 5.15 (b)",
+ "27002: 8.3 (b)",
+ "27002: 8.16 (b)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "SC-3",
+ "SC-7",
+ "SC-7(20)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.AC-4",
+ "PR.AC-5"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.AA-05",
+ "PR.IR-01",
+ "PR.PS-01",
+ "PR.PS-06",
+ "DE.CM-09"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "2.6",
+ "8.3.1",
+ "10.8",
+ "11.3",
+ "A3.2.1",
+ "A3.3.1"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "A1.1.1",
+ "A1.1.2",
+ "A1.1.3"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "cloudsql_instance_private_ip_assignment",
+ "cloudstorage_uses_vpc_service_controls",
+ "compute_instance_public_ip",
+ "compute_network_default_in_use",
+ "compute_network_not_legacy"
+ ]
+ },
+ {
+ "Id": "IVS-07",
+ "Description": "Use secure and encrypted communication channels when migrating servers, services, applications, or data to cloud environments. Such channels must include only up-to-date and approved protocols.",
+ "Name": "Migration to Cloud Environments",
+ "Attributes": [
+ {
+ "Section": "Infrastructure & Virtualization Security",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC6.1",
+ "CC6.7"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "IVS-10"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.1.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "IM1.4",
+ "IM1.4",
+ "NC1.4",
+ "SC2.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.13.1.1",
+ "27002: 13.1.1",
+ "27017: 13.1.1",
+ "27018: 13.1.1",
+ "27001: A.13.1.2",
+ "27002: 13.1.2",
+ "27017: 13.1.2",
+ "27018: 13.1.2",
+ "27001: A.13.1.3",
+ "27002: 13.1.3",
+ "27017: 13.1.3",
+ "27018: 13.1.3",
+ "27001: A.13.2.1",
+ "27002: 13.2.1",
+ "27017: 13.2.1",
+ "27018: 13.2.1",
+ "27001: A.13.2.2",
+ "27002: 13.2.2",
+ "27017: 13.2.2",
+ "27018: 13.2.2",
+ "27001: A.13.2.3",
+ "27002: 13.2.3",
+ "27017: 13.2.3",
+ "27018: 13.2.3",
+ "27001: A.13.2.4",
+ "27002: 13.2.4",
+ "27017: 13.2.4",
+ "27018: 13.2.4"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.14",
+ "27001: A.8.20",
+ "27001: A.8.24",
+ "27002: 8.20 (e)",
+ "27002: 8.24 Guidance (b,f), other information (a)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "AC-17",
+ "AC-20",
+ "SC-7",
+ "SC-7(28)",
+ "SC-8",
+ "SC-8(1)",
+ "SC-12",
+ "SC-23",
+ "SC-29",
+ "SI-7",
+ "SI-7(1)-(3)",
+ "SI-7(5)-(10)",
+ "SI-7(12)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.DS-2",
+ "PR.PT-4"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.DS-02"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "4.2.1"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "cloudsql_instance_ssl_connections"
+ ]
+ },
+ {
+ "Id": "IVS-09",
+ "Description": "Define, implement and evaluate processes, procedures and defense-in-depth techniques for protection, detection, and timely response to network-based attacks.",
+ "Name": "Network Defense",
+ "Attributes": [
+ {
+ "Section": "Infrastructure & Virtualization Security",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "CSP-Owned",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC6.6",
+ "CC6.8",
+ "CC7.1",
+ "CC7.2",
+ "CC7.5"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "IVS-13"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "13.3",
+ "13.8"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.2.3",
+ "5.2.4",
+ "5.2.5",
+ "5.2.7",
+ "5.3.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "NC1.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: 6.1",
+ "27001: 6.2",
+ "27001: A.14.1.2",
+ "27002: 14.1.2",
+ "27017: 14.1.2",
+ "27001: A.11.1.4",
+ "27002: 11.1.4",
+ "27017: 11.1.4",
+ "27018: 16.1.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: 6.1",
+ "27001: 6.2",
+ "27001: A.5.24",
+ "27001: A.5.26",
+ "27001: A.8.8",
+ "27001: A.8.16",
+ "27001: A.8.20",
+ "27001: A.8.21",
+ "27001: A.8.22",
+ "27001: A.8.26",
+ "27002: 8.8 (i)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "PL-8",
+ "PL-8(1)",
+ "SC-5",
+ "SC-5(1)",
+ "SC-5(3)",
+ "SC-7",
+ "SC-7(13)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "DE.AE-1",
+ "DE.DP-1",
+ "DE.CM-1",
+ "DE.CM-7",
+ "PR.AC-5",
+ "RS.MI-2",
+ "PR.DS-2",
+ "RS.RP-1"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "ID.AM-03",
+ "DE.CM-01",
+ "PR.IR-01",
+ "RS.MA-01",
+ "RS.MI-01",
+ "RS.MI-02"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "6.6",
+ "1.1",
+ "1.2",
+ "1.3",
+ "1.5",
+ "12.10.5"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "1.1.1",
+ "1.3.1",
+ "1.3.2",
+ "1.3.3",
+ "1.4.1",
+ "1.4.2",
+ "1.4.3",
+ "1.4.4",
+ "1.4.5",
+ "1.5.1",
+ "12.10.1"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "compute_firewall_rdp_access_from_the_internet_allowed",
+ "compute_firewall_ssh_access_from_the_internet_allowed",
+ "compute_loadbalancer_logging_enabled",
+ "compute_public_address_shodan",
+ "dns_dnssec_disabled"
+ ]
+ },
+ {
+ "Id": "LOG-02",
+ "Description": "Define, implement and evaluate processes, procedures and technical measures to ensure the security and retention of audit logs.",
+ "Name": "Audit Logs Protection",
+ "Attributes": [
+ {
+ "Section": "Logging and Monitoring",
+ "CCMLite": "No",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "IVS-01"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "8.1",
+ "8.9",
+ "8.1"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "3.1.3",
+ "5.1.2",
+ "5.2.4"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "TM1.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.18.1.3",
+ "27002: 18.1.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.28",
+ "27001: A.5.33",
+ "27001: A.8.15"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "AU-4",
+ "AU-11"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.AC-4",
+ "PR.IP-4",
+ "PR.IP-6",
+ "PR.PT-1",
+ "PR.DS-1"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.AA-05",
+ "PR.DS-01",
+ "PR.DS-02",
+ "ID.AM-08",
+ "PR.DS-11",
+ "PR.PS-04"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "10.5",
+ "10.7"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "10.3.1",
+ "10.3.2",
+ "10.3.3",
+ "10.3.4",
+ "10.5.1"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "cloudstorage_bucket_log_retention_policy_lock",
+ "cloudstorage_bucket_logging_enabled",
+ "logging_sink_created"
+ ]
+ },
+ {
+ "Id": "LOG-03",
+ "Description": "Identify and monitor security-related events within applications and the underlying infrastructure. Define and implement a system to generate alerts to responsible stakeholders based on such events and corresponding metrics.",
+ "Name": "Security Monitoring and Alerting",
+ "Attributes": [
+ {
+ "Section": "Logging and Monitoring",
+ "CCMLite": "No",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC6.8",
+ "CC7.3"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "SEF-03",
+ "SEF-05"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "8.5"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.2.4",
+ "5.2.7",
+ "1.6.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "TM1.2",
+ "TM1.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.12.4.1",
+ "27002: 12.4.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.28",
+ "27001: A.8.15"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "AU-5",
+ "AU-5(2)",
+ "AU-13"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "DE.AE-1",
+ "DE.AE-2",
+ "DE.AE-3",
+ "DE.AE-5",
+ "DE.CM-1",
+ "DE.CM-2",
+ "DE.CM-3",
+ "DE.CM-4",
+ "DE.CM-5",
+ "DE.CM-6",
+ "DE.CM-7",
+ "DE.DP-1",
+ "DE.DP-4",
+ "DE.AE-4"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.PS-04",
+ "DE.AE-02",
+ "DE.AE-03",
+ "DE.AE-04",
+ "DE.AE-06",
+ "DE.AE-07",
+ "DE.AE-08",
+ "DE.CM-01",
+ "DE.CM-02",
+ "DE.CM-03",
+ "DE.CM-06",
+ "DE.CM-09"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "10.2"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "10.2.1",
+ "10.2.2",
+ "10.4.1.1",
+ "10.4.2.1",
+ "10.4.3"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "logging_log_metric_filter_and_alert_for_audit_configuration_changes_enabled",
+ "logging_log_metric_filter_and_alert_for_bucket_permission_changes_enabled",
+ "logging_log_metric_filter_and_alert_for_compute_configuration_changes_enabled",
+ "logging_log_metric_filter_and_alert_for_custom_role_changes_enabled",
+ "logging_log_metric_filter_and_alert_for_project_ownership_changes_enabled",
+ "logging_log_metric_filter_and_alert_for_sql_instance_configuration_changes_enabled",
+ "logging_log_metric_filter_and_alert_for_vpc_firewall_rule_changes_enabled",
+ "logging_log_metric_filter_and_alert_for_vpc_network_changes_enabled",
+ "logging_log_metric_filter_and_alert_for_vpc_network_route_changes_enabled"
+ ]
+ },
+ {
+ "Id": "LOG-04",
+ "Description": "Restrict audit logs access to authorized personnel and maintain records that provide unique access accountability.",
+ "Name": "Audit Logs Access and Accountability",
+ "Attributes": [
+ {
+ "Section": "Logging and Monitoring",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "IVS-01"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "3.14"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "3.1.1",
+ "4.1.2",
+ "4.1.3",
+ "4.2.1",
+ "5.2.4"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "TM1.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.12.4.2",
+ "27001: A.12.4.1",
+ "27002: 12.4.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.33",
+ "27001: A.8.15"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "AU-9",
+ "AU-9(4)",
+ "AU-9(6)",
+ "AU-10"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.AC-1",
+ "PR.AC-4"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.AA-05",
+ "PR.PS-04"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "10.1",
+ "10.2.1",
+ "10.2.3",
+ "10.5.1",
+ "10.5.2"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "10.2.1.3",
+ "10.3.1"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "cloudstorage_bucket_public_access",
+ "cloudstorage_bucket_uniform_bucket_level_access",
+ "iam_audit_logs_enabled",
+ "kms_key_not_publicly_accessible"
+ ]
+ },
+ {
+ "Id": "LOG-05",
+ "Description": "Monitor security audit logs to detect activity outside of typical or expected patterns. Establish and follow a defined process to review and take appropriate and timely actions on detected anomalies.",
+ "Name": "Audit Logs Monitoring and Response",
+ "Attributes": [
+ {
+ "Section": "Logging and Monitoring",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC7.2"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "8.8",
+ "8.11"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "1.6.1",
+ "1.6.2",
+ "5.2.4"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "TM1.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.12.4.3",
+ "27002: 12.4.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.8.15",
+ "27001: A.8.16"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "AU-6",
+ "AU-6(1)",
+ "AU-6(5)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "DE.AE-3",
+ "PR.PT-1",
+ "RS.AN-1",
+ "RS.CO-1.",
+ "DE.AE-1",
+ "DE.AE-5",
+ "DE.DP-4"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "ID.AM-03",
+ "PR.PS-04",
+ "DE.AE-02",
+ "DE.AE-03",
+ "DE.AE-06",
+ "DE.AE-07",
+ "DE.AE-08",
+ "DE.CM-01",
+ "DE.CM-02",
+ "DE.CM-03",
+ "DE.CM-06",
+ "DE.CM-09"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "10.6",
+ "10.6.1"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "10.4.1.1",
+ "10.4.2.1"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "logging_log_metric_filter_and_alert_for_project_ownership_changes_enabled",
+ "logging_log_metric_filter_and_alert_for_audit_configuration_changes_enabled",
+ "logging_log_metric_filter_and_alert_for_bucket_permission_changes_enabled",
+ "logging_log_metric_filter_and_alert_for_compute_configuration_changes_enabled",
+ "logging_log_metric_filter_and_alert_for_custom_role_changes_enabled",
+ "logging_log_metric_filter_and_alert_for_sql_instance_configuration_changes_enabled",
+ "logging_log_metric_filter_and_alert_for_vpc_firewall_rule_changes_enabled",
+ "logging_log_metric_filter_and_alert_for_vpc_network_changes_enabled",
+ "logging_log_metric_filter_and_alert_for_vpc_network_route_changes_enabled"
+ ]
+ },
+ {
+ "Id": "LOG-07",
+ "Description": "Establish, document and implement which information meta/data system events should be logged. Review and update the scope at least annually or whenever there is a change in the threat environment.",
+ "Name": "Logging Scope",
+ "Attributes": [
+ {
+ "Section": "Logging and Monitoring",
+ "CCMLite": "No",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC7.2"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "8.1"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.2.4"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "TM1.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: 7.5.3",
+ "27001: A.12.4.1",
+ "27002: 12.4.1",
+ "27017: 12.4.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: 7.5.3",
+ "27001: A.8.15"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "AU-1",
+ "AU-14",
+ "AU-16"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "ID.SC-3",
+ "ID.SC-4",
+ "PR.PT-1",
+ "ID.GV-1"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.PS-04"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "10.3"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "10.2.1",
+ "10.2.2"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "cloudstorage_audit_logs_enabled",
+ "cloudstorage_bucket_logging_enabled",
+ "compute_network_dns_logging_enabled",
+ "compute_subnet_flow_logs_enabled",
+ "iam_audit_logs_enabled"
+ ]
+ },
+ {
+ "Id": "LOG-08",
+ "Description": "Generate audit records containing relevant security information.",
+ "Name": "Log Records",
+ "Attributes": [
+ {
+ "Section": "Logging and Monitoring",
+ "CCMLite": "No",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC7.2"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "8.2"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.2.4"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "TM1.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.12.4.1",
+ "27002: 12.4.1",
+ "27017: 12.4.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.8.15"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "AU-3",
+ "AU-3(1)",
+ "AU-3(3)",
+ "AU-6",
+ "AU-6(8)",
+ "AU-12",
+ "AU-12(1)",
+ "AU-12(2)",
+ "AU-12(3)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.PT-1",
+ "DE.AE-3",
+ "DE.CM-1",
+ "DE.CM-2",
+ "DE.CM-3",
+ "DE.CM-6",
+ "DE.CM-7"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.PS-04",
+ "DE.CM-01",
+ "DE.CM-02",
+ "DE.CM-03",
+ "DE.CM-06",
+ "DE.CM-09"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "10.3"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "10.2.2"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "iam_audit_logs_enabled",
+ "compute_subnet_flow_logs_enabled",
+ "compute_loadbalancer_logging_enabled",
+ "compute_network_dns_logging_enabled",
+ "cloudstorage_audit_logs_enabled",
+ "cloudstorage_bucket_logging_enabled",
+ "logging_sink_created",
+ "cloudsql_instance_postgres_log_connections_flag",
+ "cloudsql_instance_postgres_log_disconnections_flag",
+ "cloudsql_instance_postgres_log_statement_flag",
+ "cloudsql_instance_postgres_enable_pgaudit_flag"
+ ]
+ },
+ {
+ "Id": "LOG-09",
+ "Description": "The information system protects audit records from unauthorized access, modification, and deletion.",
+ "Name": "Log Protection",
+ "Attributes": [
+ {
+ "Section": "Logging and Monitoring",
+ "CCMLite": "No",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "GRM-04",
+ "IVS-01"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.2.4",
+ "4.2.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "TM1.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.12.4.2",
+ "27002: 12.4.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.8.15"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "AU-9",
+ "AU-9(2)",
+ "AU-9(3)",
+ "AU-9(4)",
+ "AU-12(3)",
+ "AU-12(3)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.AC-4",
+ "PR.IP-4",
+ "PR.IP-6",
+ "PR.PT-1",
+ "PR.DS-1",
+ "PR.DS-6"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.AA-05",
+ "PR.DS-01",
+ "PR.DS-02",
+ "PR.DS-11"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "10.5",
+ "10.5.1",
+ "10.5.2"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "10.3.1",
+ "10.3.2",
+ "10.3.3",
+ "10.3.4"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "cloudstorage_bucket_log_retention_policy_lock",
+ "cloudstorage_bucket_uniform_bucket_level_access"
+ ]
+ },
+ {
+ "Id": "LOG-10",
+ "Description": "Establish and maintain a monitoring and internal reporting capability over the operations of cryptographic, encryption and key management policies, processes, procedures, and controls.",
+ "Name": "Encryption Monitoring and Reporting",
+ "Attributes": [
+ {
+ "Section": "Logging and Monitoring",
+ "CCMLite": "No",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC6.1",
+ "CC7.2"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "EKM-02",
+ "EKM-03"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "4.2.1",
+ "5.1.1",
+ "5.1.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "TS2.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.10.1",
+ "27002: 10.1",
+ "27001: A.10.1.2",
+ "27017: 10.1.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.8.24"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "AU-1",
+ "AU-9",
+ "AU-9(3)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "ID.GV-1",
+ "PR.PT-1"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.PS-04",
+ "DE.CM-09"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "10.1.1",
+ "10.2.1",
+ "10.4.1"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "kms_key_rotation_enabled"
+ ]
+ },
+ {
+ "Id": "LOG-11",
+ "Description": "Log and monitor key lifecycle management events to enable auditing and reporting on usage of cryptographic keys.",
+ "Name": "Transaction/Activity Logging",
+ "Attributes": [
+ {
+ "Section": "Logging and Monitoring",
+ "CCMLite": "No",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC6.1",
+ "CC7.2"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "EKM-02"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.1.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "TS2.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.10.1.2",
+ "27017: 10.1.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.8.24"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "AU-9",
+ "AU-9(3)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.PT-1",
+ "DE.AE-3"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.PS-04",
+ "DE.CM-09"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "cloudstorage_audit_logs_enabled",
+ "iam_audit_logs_enabled",
+ "logging_sink_created"
+ ]
+ },
+ {
+ "Id": "LOG-13",
+ "Description": "Define, implement and evaluate processes, procedures and technical measures for the reporting of anomalies and failures of the monitoring system and provide immediate notification to the accountable party.",
+ "Name": "Failures and Anomalies Reporting",
+ "Attributes": [
+ {
+ "Section": "Logging and Monitoring",
+ "CCMLite": "No",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC2.3",
+ "CC7.3"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "SEF-03"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "1.6.1",
+ "5.2.4"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "TM1.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.16.1.1",
+ "27002: 16.1.1",
+ "27001: A.16.1.2",
+ "27017: 16.1.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.24",
+ "27001: A.6.8",
+ "27002: 6.8 (g)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "AU-5",
+ "AU-5(2)",
+ "AU-6",
+ "AU-6(3)",
+ "AU-6(4)",
+ "AU-6(5)",
+ "AU-16"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "DE.DP-3",
+ "DE.DP-4"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.PS-04",
+ "DE.AE-06"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "10.6"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "10.4.3",
+ "10.7.1",
+ "10.7.2",
+ "10.7.3"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "logging_log_metric_filter_and_alert_for_audit_configuration_changes_enabled",
+ "logging_log_metric_filter_and_alert_for_custom_role_changes_enabled",
+ "logging_log_metric_filter_and_alert_for_project_ownership_changes_enabled"
+ ]
+ },
+ {
+ "Id": "SEF-03",
+ "Description": "'Establish, document, approve, communicate, apply, evaluate and maintain a security incident response plan, which includes but is not limited to: relevant internal departments, impacted CSCs, and other business critical relationships (such as supply-chain) that may be impacted.'",
+ "Name": "Incident Response Plans",
+ "Attributes": [
+ {
+ "Section": "Security Incident Management, E-Discovery, & Cloud Forensics",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC7.2",
+ "CC7.3",
+ "CC7.4"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "BCR-02"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "17.2",
+ "17.4"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "1.6.2",
+ "1.6.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "TM2.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: 5.2",
+ "27001: 7.3",
+ "27001: 7.4",
+ "27001: 7.5",
+ "27001: A.16.1.5",
+ "27002: 16.1.5",
+ "27017: 16.1.5",
+ "27017: CLD.12.1.5",
+ "27018: 16.1.5"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: 5.2",
+ "27001: 7.3",
+ "27001: 7.4",
+ "27001: 7.5",
+ "27001: A.5.26",
+ "27002: 5.26 (e,f)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "IR-1",
+ "IR-2",
+ "IR-2(1)-(3)",
+ "IR-3",
+ "IR-3(1)-(3)",
+ "IR-4",
+ "IR-4(1)-(15)",
+ "IR-5",
+ "IR-5(1)",
+ "IR-6",
+ "IR-6(1)-(3)",
+ "IR-7",
+ "IR-7(1)",
+ "IR-7(2)",
+ "IR-8",
+ "IR-8(1)",
+ "IR-9",
+ "IR-9(1)-(4)",
+ "PM-12"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "RS.CO-1",
+ "RS.CO-4",
+ "ID.AM-6",
+ "ID.GV-2",
+ "ID.SC-5",
+ "PR.IP-9",
+ "PR.IP10"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.AT-01",
+ "PR.AT-02",
+ "RS.MA-01",
+ "GV.SC-08",
+ "ID.IM-02",
+ "ID.IM-04",
+ "RC.RP-01"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "12.1",
+ "12.10.1"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "12.10.1",
+ "12.10.5"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": []
+ },
+ {
+ "Id": "SEF-06",
+ "Description": "Define, implement and evaluate processes, procedures and technical measures supporting business processes to triage security-related events.",
+ "Name": "Event Triage Processes",
+ "Attributes": [
+ {
+ "Section": "Security Incident Management, E-Discovery, & Cloud Forensics",
+ "CCMLite": "No",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC7.3"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "SEF-02"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "1.6.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "TM1.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.16.1.4",
+ "27002: 16.1.4",
+ "27017: 16.1.4",
+ "27018: 16.1.4",
+ "27001: A.16.1.5",
+ "27002: 16.1.5",
+ "27017: 16.1.5",
+ "27018: 16.1.5"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.25"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "CA-7",
+ "CA-7(3)",
+ "CA-7(4)",
+ "CA-7(5)",
+ "CA-7(6)",
+ "IR-4",
+ "IR-4(1)",
+ "IR-4(3)",
+ "IR-4(4)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "DE.AE-1",
+ "DE.AE-2",
+ "DE.AE-4",
+ "RS.RP-1",
+ "RS.AN-2"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "RS.MA-02",
+ "RS.MA-03",
+ "RS.AN-03",
+ "DE.AE-02",
+ "DE.AE-04",
+ "DE.AE-06",
+ "DE.AE-07",
+ "DE.AE-08",
+ "RS.MI-02",
+ "RC.RP-02"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "12.5.2"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "12.10.1"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "iam_audit_logs_enabled",
+ "logging_sink_created"
+ ]
+ },
+ {
+ "Id": "SEF-08",
+ "Description": "Maintain points of contact for applicable regulation authorities, national and local law enforcement, and other legal jurisdictional authorities.",
+ "Name": "Points of Contact Maintenance",
+ "Attributes": [
+ {
+ "Section": "Security Incident Management, E-Discovery, & Cloud Forensics",
+ "CCMLite": "No",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC2.3"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "SEF-01"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "17.2"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "1.6.2",
+ "1.6.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "SM2.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: 4.2",
+ "27001: A.6.1.3",
+ "27002: 6.1.3",
+ "27017: 6.1.3",
+ "27018: 6.1.3",
+ "27001: A.16.1.1",
+ "27002: 16.1.1",
+ "27001: A.18.1.1",
+ "27002: 18.1.1",
+ "27017: 18.1.1",
+ "27018: 18.1.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.5",
+ "27001: A.5.24",
+ "27002: 5.24 Incident management procedure (d)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "IR-4",
+ "IR-4(8)",
+ "IR-6",
+ "IR-6(3)",
+ "IR-7",
+ "IR-7(2)",
+ "PM-21",
+ "PM-23",
+ "PM-26"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "ID.GV-2",
+ "RS.CO-3",
+ "RS.CO-4"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "GV.RR-02",
+ "RS.CO-02",
+ "RS.CO-03"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "12.10.1"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "iam_organization_essential_contacts_configured"
+ ]
+ },
+ {
+ "Id": "TVM-02",
+ "Description": "Establish, document, approve, communicate, apply, evaluate and maintain policies and procedures to protect against malware on managed assets. Review and update the policies and procedures at least annually.",
+ "Name": "Malware Protection Policy and Procedures",
+ "Attributes": [
+ {
+ "Section": "Threat & Vulnerability Management",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC5.3",
+ "CC6.8"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "TVM-01",
+ "GRM-06",
+ "GRM-09"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "9.7",
+ "10.1"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "1.1.1",
+ "1.5.1",
+ "5.2.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "TS1.2",
+ "TS1.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: 5.1",
+ "27001: 5.2",
+ "27001: 7.3",
+ "27001: 7.4",
+ "27001: 7.5",
+ "27001: 9.1",
+ "27001: 9.3",
+ "27001: A.5",
+ "27002: 5",
+ "27001: A.12.2.1",
+ "27001: A.6.2.1",
+ "27002: 6.2.1 (h)",
+ "27001: A.6.2.2",
+ "27002: 6.2.2 (j)",
+ "27001: A.7.2.2",
+ "27002: 7.2.2 (d)",
+ "27001: A.10.1.1",
+ "27002: 10.1.1 (g)",
+ "27001: A.13.2.1",
+ "27002: 13.2.1 (b)",
+ "27001: A.15.1.2",
+ "27017: 15.1.2",
+ "27001: A.12.2.1",
+ "27002: 12.2.1 (a),(d)",
+ "27017: CLD.9.5.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: 5.1",
+ "27001: 5.2",
+ "27001: 7.3",
+ "27001: 7.4",
+ "27001: 7.5",
+ "27001: 9.1",
+ "27001: 9.3",
+ "27001: A.5.1",
+ "27001: A.5.4",
+ "27001: A.5.7",
+ "27001: A.5.37",
+ "27001: A.8.7",
+ "27002: 5.7 (b)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "RA-3",
+ "RA-3(3)",
+ "RA-5",
+ "RA-5(3)",
+ "RA-5(5)",
+ "SI-3",
+ "SI-3(4)",
+ "SI-3(10)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "ID.GV-1",
+ "DE.CM-4",
+ "DE.CM-5"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "GV.PO-01",
+ "GV.PO-02",
+ "ID.IM-03",
+ "DE.CM-01",
+ "DE.CM-09"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "5.4",
+ "12.1",
+ "12.1.1",
+ "12.3.1",
+ "12.5.1",
+ "12.11"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "12.1.1",
+ "12.1.2",
+ "5.1.1",
+ "5.3.2.1"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": []
+ },
+ {
+ "Id": "TVM-03",
+ "Description": "Define, implement and evaluate processes, procedures and technical measures to enable both scheduled and emergency responses to vulnerability identifications, based on the identified risk.",
+ "Name": "Vulnerability Remediation Schedule",
+ "Attributes": [
+ {
+ "Section": "Threat & Vulnerability Management",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC5.3",
+ "CC7.1",
+ "CC7.4"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "TVM-02"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "7.2",
+ "7.7",
+ "17.9"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.2.5"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "TM1.1",
+ "TM2.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: 6.1.3",
+ "27001: A.12.2.1",
+ "27001: A.12.6.1",
+ "27002: 12.6.1(c)(d)(j)",
+ "27018: 12.6.1(k)(i)"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: 6.1.3",
+ "27001: A.8.7",
+ "27001: A.8.8",
+ "27001: A.8.32",
+ "27002: 8.7",
+ "27002: 8.8",
+ "27002: 8.32"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "PM-31",
+ "RA-3",
+ "RA-3(1)",
+ "RA-5",
+ "RA-5(2)-(4)",
+ "RA-5(6)",
+ "SI-3",
+ "SI-3(10)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "RS.AN-5",
+ "PR.IP-12"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "ID.RA-01",
+ "ID.RA-06",
+ "ID.RA-08",
+ "PR.PS-02",
+ "PR.PS-03"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "6.1",
+ "6.1.a",
+ "6.1.b"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "6.1.1",
+ "6.3.1",
+ "6.3.2",
+ "6.3.3",
+ "12.10.1"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": []
+ },
+ {
+ "Id": "TVM-04",
+ "Description": "Define, implement and evaluate processes, procedures and technical measures to update detection tools, threat signatures, and indicators of compromise on a weekly, or more frequent basis.",
+ "Name": "Detection Updates",
+ "Attributes": [
+ {
+ "Section": "Threat & Vulnerability Management",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC7.2"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "No mapping"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "10.2"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.2.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "TS1.3",
+ "TS1.4",
+ "TM1.3",
+ "TM1.4",
+ "IM1.5"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: 6.1.3",
+ "27001: A.5.1.1",
+ "27002: 5.1.1 (h)",
+ "27001: A.12.6.1",
+ "27002: 12.6.1 (b),(c)"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: 6.1.3",
+ "27001: A.5.1",
+ "27001: A.8.8",
+ "27001: A.8.15",
+ "27001: A.8.16",
+ "27002: 5.1",
+ "27002: 5.37",
+ "27002: 8.8",
+ "27002: 8.15 (d)",
+ "27002: 8.16 (d,e)",
+ "27002: 8.31 2nd (a)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "CM-7",
+ "CM-7(4)",
+ "RA-3",
+ "RA-3(3)",
+ "RA-5(2)",
+ "SA-10",
+ "SA-10(5)",
+ "SA-11",
+ "SA-11(2)",
+ "SI-2",
+ "SI-2(4)",
+ "SI-3",
+ "SI-3(4)",
+ "SI-4",
+ "SI-4(9)",
+ "SI-4(24)",
+ "SI-8",
+ "SI-8(2)",
+ "SI-8(3)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "DE.DP-5",
+ "PR.IP-12"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.PS-02",
+ "ID.RA-02"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "5.2",
+ "5.2a",
+ "5.2b",
+ "5.2c"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "5.3.1"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "artifacts_container_analysis_enabled",
+ "gcr_container_scanning_enabled"
+ ]
+ },
+ {
+ "Id": "TVM-05",
+ "Description": "Define, implement and evaluate processes, procedures and technical measures to identify updates for applications which use third party or open source libraries according to the organization's vulnerability management policy.",
+ "Name": "External Library Vulnerabilities",
+ "Attributes": [
+ {
+ "Section": "Threat & Vulnerability Management",
+ "CCMLite": "No",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "CSP-Owned",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC3.2"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "No mapping"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "2.6"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "TM1.1",
+ "SD2.3"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: 6.1.3",
+ "27001: A.12.6.2",
+ "27002: 12.6.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: 6.1.3",
+ "27001: A 5.6",
+ "27001: A.8.19",
+ "27001: A.8.8",
+ "27001: A.8.28",
+ "27001: A.8.31",
+ "27002: 5.6 (c)",
+ "27001: 8.19",
+ "27001: 8.8",
+ "27001: 8.28",
+ "27001: 8.31"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "RA-5",
+ "RA-5(3)",
+ "SA-11",
+ "SA-11(2)",
+ "SA-11(5)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "DE.DP-5",
+ "PR.IP-12"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "ID.RA-01",
+ "ID.RA-03",
+ "PR.PS-02"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "6.1",
+ "6.2",
+ "6.3.2"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "6.3.1",
+ "6.3.2",
+ "6.3.3"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "artifacts_container_analysis_enabled",
+ "gcr_container_scanning_enabled"
+ ]
+ },
+ {
+ "Id": "TVM-07",
+ "Description": "Define, implement and evaluate processes, procedures and technical measures for the detection of vulnerabilities on organizationally managed assets at least monthly.",
+ "Name": "Vulnerability Identification",
+ "Attributes": [
+ {
+ "Section": "Threat & Vulnerability Management",
+ "CCMLite": "Yes",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC7.1"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "TVM-02"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "7.1",
+ "7.5",
+ "7.6"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.2.5",
+ "5.2.6"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "TM1.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.12.6",
+ "27001: A.12.6.1",
+ "27002: 12.6.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.8.8",
+ "27002: 8.8"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "RA-5",
+ "RA-5(4)",
+ "RA-5(5)",
+ "SA-11",
+ "SA-11(5)",
+ "SA-15(5)",
+ "SC-7",
+ "SC-7(10)",
+ "SI-3(8)",
+ "SI-3(10)",
+ "SI-7",
+ "SI-7(9)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "ID.RA-1",
+ "DE.CM-8",
+ "PR.IP-12"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "ID.RA-01"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "6.1",
+ "11.2",
+ "11.2.1"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "6.3.1",
+ "6.3.2",
+ "6.3.3",
+ "11.3.2",
+ "11.3.2.1"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "artifacts_container_analysis_enabled",
+ "compute_public_address_shodan",
+ "gcr_container_scanning_enabled"
+ ]
+ },
+ {
+ "Id": "UEM-08",
+ "Description": "Protect information from unauthorized disclosure on managed endpoint devices with storage encryption.",
+ "Name": "Storage Encryption",
+ "Attributes": [
+ {
+ "Section": "Universal Endpoint Management",
+ "CCMLite": "No",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC6.1",
+ "CC6.7"
+ ]
+ },
+ {
+ "ReferenceId": "CCM v3.0.1",
+ "Identifiers": [
+ "MOS-11"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "3.6"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.1.2",
+ "3.1.4"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "PA1.2",
+ "PA1.3",
+ "PA1.5",
+ "PA2.2",
+ "PM1.4"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.11.2.7",
+ "27002: 11.2.7",
+ "27001: A.18.1.1",
+ "27017: 18.1.1",
+ "27001: A.12.3.1",
+ "27017: 12.3.1",
+ "27018: A.11.4",
+ "27018: A.11.5"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.8.1",
+ "27002: 8.1 (h)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "AC-19(5)",
+ "SC-28",
+ "SC-28(1)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.DS-1"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.DS-01"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "3.4",
+ "3.6"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "3.5.1",
+ "3.6"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": [
+ "bigquery_dataset_cmk_encryption",
+ "bigquery_table_cmk_encryption",
+ "compute_instance_confidential_computing_enabled",
+ "compute_instance_encryption_with_csek_enabled",
+ "dataproc_encrypted_with_cmks_disabled"
+ ]
+ },
+ {
+ "Id": "UEM-11",
+ "Description": "Configure managed endpoints with Data Loss Prevention (DLP) technologies and rules in accordance with a risk assessment.",
+ "Name": "Data Loss Prevention",
+ "Attributes": [
+ {
+ "Section": "Universal Endpoint Management",
+ "CCMLite": "No",
+ "IaaS": "Shared",
+ "PaaS": "Shared",
+ "SaaS": "Shared",
+ "ScopeApplicability": [
+ {
+ "ReferenceId": "AICPA TSC 2017",
+ "Identifiers": [
+ "CC6.7"
+ ]
+ },
+ {
+ "ReferenceId": "CIS v8.0",
+ "Identifiers": [
+ "3.13"
+ ]
+ },
+ {
+ "ReferenceId": "ENX ISA v6.0",
+ "Identifiers": [
+ "5.2.7"
+ ]
+ },
+ {
+ "ReferenceId": "ISF SOGP 2022",
+ "Identifiers": [
+ "IM1.5",
+ "PA2.2"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2013,27002:2013,27017:2015,27018:2019",
+ "Identifiers": [
+ "27001: A.12.3",
+ "27002: 12.3",
+ "27001: A.8.3.1",
+ "27002: 8.3.1",
+ "27001: A.12.2",
+ "27002: 12.2",
+ "27001: A.18.1.3",
+ "27002: 18.1.3",
+ "27001: A.6.1.1",
+ "27017: 6.1.1",
+ "27018: 12.3.1",
+ "27018: 10.1"
+ ]
+ },
+ {
+ "ReferenceId": "ISO/IEC 27001:2022, 27002:2022",
+ "Identifiers": [
+ "27001: A.5.12",
+ "27001: A.8.3"
+ ]
+ },
+ {
+ "ReferenceId": "NIST 800-53 rev 5",
+ "Identifiers": [
+ "SC-7",
+ "SC-7(10)"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v1.1",
+ "Identifiers": [
+ "PR.DS-5"
+ ]
+ },
+ {
+ "ReferenceId": "NIST CSF v2.0",
+ "Identifiers": [
+ "PR.DS-02",
+ "PR.DS-10",
+ "PR.PS-01",
+ "ID.AM-08",
+ "DE.CM-09"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v3.2.1",
+ "Identifiers": [
+ "A3.2.6"
+ ]
+ },
+ {
+ "ReferenceId": "PCI DSS v4.0",
+ "Identifiers": [
+ "A3.2.6"
+ ]
+ }
+ ]
+ }
+ ],
+ "Checks": []
+ }
+ ]
+}
diff --git a/prowler/compliance/github/cis_1.0_github.json b/prowler/compliance/github/cis_1.0_github.json
index f016acaabb..e675470169 100644
--- a/prowler/compliance/github/cis_1.0_github.json
+++ b/prowler/compliance/github/cis_1.0_github.json
@@ -778,7 +778,9 @@
{
"Id": "1.3.9",
"Description": "Confirm the domains an organization owns with a \"Verified\" badge.",
- "Checks": [],
+ "Checks": [
+ "organization_verified_badge"
+ ],
"Attributes": [
{
"Section": "1 Source Code",
diff --git a/prowler/compliance/m365/cis_4.0_m365.json b/prowler/compliance/m365/cis_4.0_m365.json
index 156c17e26d..df9b6edfb5 100644
--- a/prowler/compliance/m365/cis_4.0_m365.json
+++ b/prowler/compliance/m365/cis_4.0_m365.json
@@ -318,7 +318,9 @@
{
"Id": "2.1.1",
"Description": "Enabling Safe Links policy for Office applications allows URL's that exist inside of Office documents and email applications opened by Office, Office Online and Office mobile to be processed against Defender for Office time-of-click verification and rewritten if required.**Note:** E5 Licensing includes a number of Built-in Protection policies. When auditing policies note which policy you are viewing, and keep in mind CIS recommendations often extend the Default or Build-in Policies provided by MS. In order to **Pass** the highest priority policy must match all settings recommended.",
- "Checks": [],
+ "Checks": [
+ "defender_safelinks_policy_enabled"
+ ],
"Attributes": [
{
"Section": "2 Microsoft 365 Defender",
@@ -385,7 +387,9 @@
{
"Id": "2.1.4",
"Description": "The Safe Attachments policy helps protect users from malware in email attachments by scanning attachments for viruses, malware, and other malicious content. When an email attachment is received by a user, Safe Attachments will scan the attachment in a secure environment and provide a verdict on whether the attachment is safe or not.",
- "Checks": [],
+ "Checks": [
+ "defender_safe_attachments_policy_enabled"
+ ],
"Attributes": [
{
"Section": "2 Microsoft 365 Defender",
@@ -406,7 +410,9 @@
{
"Id": "2.1.5",
"Description": "Safe Attachments for SharePoint, OneDrive, and Microsoft Teams scans these services for malicious files.",
- "Checks": [],
+ "Checks": [
+ "defender_atp_safe_attachments_and_docs_configured"
+ ],
"Attributes": [
{
"Section": "2 Microsoft 365 Defender",
diff --git a/prowler/compliance/m365/cis_6.0_m365.json b/prowler/compliance/m365/cis_6.0_m365.json
index 93fe2e2226..192e49dcfd 100644
--- a/prowler/compliance/m365/cis_6.0_m365.json
+++ b/prowler/compliance/m365/cis_6.0_m365.json
@@ -339,7 +339,9 @@
{
"Id": "2.1.1",
"Description": "Safe Links for Office Applications is a feature in Microsoft 365 that provides URL scanning and rewriting of inbound email messages in mail flow, and time-of-click verification of URLs and links in email messages, other Microsoft 365 applications such as Teams, and other locations such as SharePoint Online. It can help protect organizations from malicious links used in phishing and other attacks.",
- "Checks": [],
+ "Checks": [
+ "defender_safelinks_policy_enabled"
+ ],
"Attributes": [
{
"Section": "2 Microsoft 365 Defender",
@@ -404,7 +406,9 @@
{
"Id": "2.1.4",
"Description": "The Safe Attachments policy helps protect users from malware in email attachments by scanning attachments for viruses, malware, and other malicious content. When an email attachment is received by a user, Safe Attachments will scan the attachment in a secure environment and provide a verdict on whether the attachment is safe or not.",
- "Checks": [],
+ "Checks": [
+ "defender_safe_attachments_policy_enabled"
+ ],
"Attributes": [
{
"Section": "2 Microsoft 365 Defender",
@@ -425,7 +429,9 @@
{
"Id": "2.1.5",
"Description": "Safe Attachments for SharePoint, OneDrive, and Microsoft Teams scans these services for malicious files.",
- "Checks": [],
+ "Checks": [
+ "defender_atp_safe_attachments_and_docs_configured"
+ ],
"Attributes": [
{
"Section": "2 Microsoft 365 Defender",
diff --git a/prowler/compliance/m365/iso27001_2022_m365.json b/prowler/compliance/m365/iso27001_2022_m365.json
index 81ae9dea2a..3335fe0f19 100644
--- a/prowler/compliance/m365/iso27001_2022_m365.json
+++ b/prowler/compliance/m365/iso27001_2022_m365.json
@@ -115,6 +115,7 @@
"defender_antiphishing_policy_configured",
"defender_antispam_outbound_policy_configured",
"defender_malware_policy_notifications_internal_users_malware_enabled",
+ "defender_safelinks_policy_enabled",
"defender_zap_for_teams_enabled",
"entra_admin_users_phishing_resistant_mfa_enabled",
"entra_identity_protection_sign_in_risk_enabled",
@@ -692,6 +693,8 @@
"defender_malware_policy_common_attachments_filter_enabled",
"defender_malware_policy_comprehensive_attachments_filter_applied",
"defender_malware_policy_notifications_internal_users_malware_enabled",
+ "defender_safe_attachments_policy_enabled",
+ "defender_safelinks_policy_enabled",
"defender_zap_for_teams_enabled",
"teams_external_domains_restricted",
"teams_external_users_cannot_start_conversations"
@@ -729,6 +732,7 @@
],
"Checks": [
"defender_antiphishing_policy_configured",
+ "defender_safelinks_policy_enabled",
"entra_admin_users_phishing_resistant_mfa_enabled"
]
},
@@ -833,10 +837,11 @@
}
],
"Checks": [
- "teams_external_domains_restricted",
- "teams_external_users_cannot_start_conversations",
+ "defender_safelinks_policy_enabled",
+ "sharepoint_external_sharing_managed",
"sharepoint_external_sharing_restricted",
- "sharepoint_external_sharing_managed"
+ "teams_external_domains_restricted",
+ "teams_external_users_cannot_start_conversations"
]
},
{
diff --git a/prowler/compliance/oraclecloud/cis_3.1_oraclecloud.json b/prowler/compliance/oraclecloud/cis_3.1_oraclecloud.json
new file mode 100644
index 0000000000..080aa60476
--- /dev/null
+++ b/prowler/compliance/oraclecloud/cis_3.1_oraclecloud.json
@@ -0,0 +1,1141 @@
+{
+ "Framework": "CIS",
+ "Name": "CIS Oracle Cloud Infrastructure Foundations Benchmark v3.1.0",
+ "Version": "3.1",
+ "Provider": "OracleCloud",
+ "Description": "The CIS Oracle Cloud Infrastructure Foundations Benchmark provides prescriptive guidance for configuring security options for Oracle Cloud Infrastructure with an emphasis on foundational, testable, and architecture agnostic settings.",
+ "Requirements": [
+ {
+ "Id": "1.1",
+ "Description": "Ensure service level admins are created to manage resources of particular service",
+ "Checks": [
+ "identity_service_level_admins_exist"
+ ],
+ "Attributes": [
+ {
+ "Section": "1. Identity and Access Management",
+ "Profile": "Level 1",
+ "AssessmentStatus": "Manual",
+ "Description": "To apply least-privilege security principle, one can create service-level administrators in corresponding groups and assigning specific users to each service-level administrative group in a tenancy. This limits administrative access in a tenancy. It means service-level administrators can only manage resources of a specific service.Example policies for global/tenant level service-administrators```Allow group VolumeAdmins to manage volume-family in tenancyAllow group ComputeAdmins to manage instance-family in tenancyAllow group NetworkAdmins to manage virtual-network-family in tenancy``````A tenancy with identity domains : An Identity Domain is a container of users, groups, Apps and other security configurations. A tenancy that has Identity Domains available comes seeded with a 'Default' identity domain. If a group belongs to a domain different than the default domain, use a domain prefix in the policy statements.Example - Allow group / to in compartment If you do not include the before the , then the policy statement is evaluated as though the group belongs to the default identity domain.```Organizations have various ways of defining service-administrators. Some may prefer creating service administrators at a tenant level and some per department or per project or even per application environment ( dev/test/production etc.). Either approach works so long as the policies are written to limit access given to the service-administrators. Example policies for compartment level service-administrators ```Allow group NonProdComputeAdmins to manage instance-family in compartment devAllow group ProdComputeAdmins to manage instance-family in compartment productionAllow group A-Admins to manage instance-family in compartment Project-AAllow group A-Admins to manage volume-family in compartment Project-A``````A tenancy with identity domains : An Identity Domain is a container of users, groups, Apps and other security configurations. A tenancy that has Identity Domains available comes seeded with a 'Default' identity domain. If a group belongs to a domain different than the default domain, use a domain prefix in the policy statements.Example - Allow group / to in compartment If you do not include the before the , then the policy statement is evaluated as though the group belongs to the default identity domain.```",
+ "RationaleStatement": "Creating service-level administrators helps in tightly controlling access to Oracle Cloud Infrastructure (OCI) services to implement the least-privileged security principle.",
+ "ImpactStatement": "",
+ "RemediationProcedure": "Refer to the [policy syntax document](https://docs.cloud.oracle.com/en-us/iaas/Content/Identity/Concepts/policysyntax.htm) and create new policies if the audit results indicate that the required policies are missing.This can be done via OCI console or OCI CLI/SDK or API.Creating a new policy:***From CLI:***```oci iam policy create [OPTIONS]```Creates a new policy in the specified compartment (either the tenancy or another of your compartments). If you're new to policies, see [Getting Started with Policies](https://docs.cloud.oracle.com/Content/Identity/Concepts/policygetstarted.htm) You must specify a name for the policy, which must be unique across all policies in your tenancy and cannot be changed.You must also specify a description for the policy (although it can be an empty string). It does not have to be unique, and you can change it anytime with UpdatePolicy.You must specify one or more policy statements in the statements array.For information about writing policies, see How [Policies Work](https://docs.cloud.oracle.com/Content/Identity/Concepts/policies.htm) and [Common Policies](https://docs.cloud.oracle.com/Content/Identity/Concepts/commonpolicies.htm).",
+ "AuditProcedure": "***From CLI:***1) [Set up OCI CLI](https://docs.cloud.oracle.com/iaas/Content/API/SDKDocs/cliinstall.htm) with an IAM administrator user who has read access to IAM resources such as groups and policies.2) Run OCI CLI command providing the root_compartment_OCIDGet the list of groups in a tenancy```oci iam group list --compartment-id | grep name``````A tenancy with identity domains : The above CLI commands work with the default identity domain only.For IaaS resource management, users and groups created in the default domain are sufficient. ```3) Ensure distinct administrative groups are created as per your organization's definition of service-administrators.4) Verify the appropriate policies are created for the service-administrators groups to have the right access to the corresponding services. Retrieve the policy statements scoped at the tenancy level and/or per compartment. ```oci iam policy list --compartment-id | grep in tenancyoci iam policy list --compartment-id | grep in compartment```The --compartment-id parameter can be changed to a child compartment to get policies associated with child compartments.```oci iam policy list --compartment-id | grep in compartment```Verify the results to ensure the right policies are created for service-administrators to have the necessary access.",
+ "AdditionalInformation": "",
+ "References": ""
+ }
+ ]
+ },
+ {
+ "Id": "1.2",
+ "Description": "Ensure permissions on all resources are given only to the tenancy administrator group",
+ "Checks": [
+ "identity_tenancy_admin_permissions_limited"
+ ],
+ "Attributes": [
+ {
+ "Section": "1. Identity and Access Management",
+ "Profile": "Level 1",
+ "AssessmentStatus": "Automated",
+ "Description": "There is a built-in OCI IAM policy enabling the Administrators group to perform any action within a tenancy. In the OCI IAM console, this policy reads:```Allow group Administrators to manage all-resources in tenancy```Administrators create more users, groups, and policies to provide appropriate access to other groups.Administrators should not allow any-other-group full access to the tenancy by writing a policy like this - ```Allow group any-other-group to manage all-resources in tenancy```The access should be narrowed down to ensure the least-privileged principle is applied.",
+ "RationaleStatement": "Permission to manage all resources in a tenancy should be limited to a small number of users in the `Administrators` group for break-glass situations and to set up users/groups/policies when a tenancy is created.No group other than `Administrators` in a tenancy should need access to all resources in a tenancy, as this violates the enforcement of the least privilege principle.",
+ "ImpactStatement": "",
+ "RemediationProcedure": "**From Console:**1) Login to OCI console.2) Go to `Identity` -> `Policies`, In the compartment dropdown, choose the root compartment. Open each policy to view the policy statements. 2) Remove any policy statement that allows any group other than `Administrators` or any service access to manage all resources in the tenancy. **From CLI:**The policies can also be updated via OCI CLI, SDK and API, with an example of the CLI commands below: * Delete a policy via the CLI: `oci iam policy delete --policy-id ` * Update a policy via the CLI: `oci iam policy update --policy-id --statements `Note: You should generally **not** delete the policy that allows the `Administrators` group the ability to manage all resources in the tenancy.",
+ "AuditProcedure": "**From CLI:**1) Run OCI CLI command providing the root compartment OCID to get the list of groups having access to manage all resources in your tenancy. ```oci iam policy list --compartment-id | grep -i to manage all-resources in tenancy ```2) Verify the results to ensure only the `Administrators` group has access to manage all resources in tenancy. Allow group Administrators to manage all-resources in tenancy",
+ "AdditionalInformation": "",
+ "References": ""
+ }
+ ]
+ },
+ {
+ "Id": "1.3",
+ "Description": "Ensure IAM administrators cannot update tenancy Administrators group",
+ "Checks": [
+ "identity_iam_admins_cannot_update_tenancy_admins"
+ ],
+ "Attributes": [
+ {
+ "Section": "1. Identity and Access Management",
+ "Profile": "Level 1",
+ "AssessmentStatus": "Automated",
+ "Description": "Tenancy administrators can create more users, groups, and policies to provide other service administrators access to OCI resources.For example, an IAM administrator will need to have access to manage resources like compartments, users, groups, dynamic-groups, policies, identity-providers, tenancy tag-namespaces, tag-definitions in the tenancy.The policy that gives IAM-Administrators or any other group full access to 'groups' resources should not allow access to the tenancy 'Administrators' group.The policy statements would look like -```Allow group IAMAdmins to inspect users in tenancyAllow group IAMAdmins to use users in tenancy where target.group.name != 'Administrators'Allow group IAMAdmins to inspect groups in tenancyAllow group IAMAdmins to use groups in tenancy where target.group.name != 'Administrators'```**Note:** You must include separate statements for 'inspect' access, because the target.group.name variable is not used by the ListUsers and ListGroups operations",
+ "RationaleStatement": "These policy statements ensure that no other group can manage tenancy administrator users or the membership to the 'Administrators' group thereby gain or remove tenancy administrator access.",
+ "ImpactStatement": "",
+ "RemediationProcedure": "**From Console:**1. Login to OCI Console.2. Select `Identity` from Services Menu.3. Select `Policies` from Identity Menu.4. Click on an individual policy under the Name heading.5. Ensure Policy statements look like this -```Allow group IAMAdmins to use users in tenancy where target.group.name != 'Administrators'Allow group IAMAdmins to use groups in tenancy where target.group.name != 'Administrators'```",
+ "AuditProcedure": "**From CLI:**1) Run the following OCI CLI commands providing the root_compartment_OCID ```oci iam policy list --compartment-id | grep -i to use users in tenancyoci iam policy list --compartment-id | grep -i to use groups in tenancy```2) Verify the results to ensure that the policy statements that grant access to use or manage users or groups in the tenancy have a condition that excludes access to `Administrators` group or to users in the Administrators group.",
+ "AdditionalInformation": "",
+ "References": ""
+ }
+ ]
+ },
+ {
+ "Id": "1.4",
+ "Description": "Ensure IAM password policy requires minimum length of 14 or greater",
+ "Checks": [
+ "identity_password_policy_minimum_length_14"
+ ],
+ "Attributes": [
+ {
+ "Section": "1. Identity and Access Management",
+ "Profile": "Level 1",
+ "AssessmentStatus": "Automated",
+ "Description": "Password policies are used to enforce password complexity requirements. IAM password policies can be used to ensure passwords are at least a certain length and are composed of certain characters. It is recommended the password policy require a minimum password length 14 characters and contain 1 non-alphabeticcharacter (Number or “Special Character”).",
+ "RationaleStatement": "In keeping with the overall goal of having users create a password that is not overly weak, an eight-character minimum password length is recommended for an MFA account, and 14 characters for a password only account. In addition, maximum password length should be made as long as possible based on system/software capabilities and not restricted by policy.In general, it is true that longer passwords are better (harder to crack), but it is also true that forced password length requirements can cause user behavior that is predictable and undesirable. For example, requiring users to have a minimum 16-character password may cause them to choose repeating patterns like fourfourfourfour or passwordpassword that meet the requirement but aren’t hard to guess. Additionally, length requirements increase the chances that users will adopt other insecure practices, like writing them down, re-using them or storing them unencrypted in their documents. Password composition requirements are a poor defense against guessing attacks. Forcing users to choose some combination of upper-case, lower-case, numbers, and special characters has a negative impact. It places an extra burden on users and manywill use predictable patterns (for example, a capital letter in the first position, followed by lowercase letters, then one or two numbers, and a “special character” at the end). Attackers know this, so dictionary attacks will often contain these common patterns and use the most common substitutions like, $ for s, @ for a, 1 for l, 0 for o.Passwords that are too complex in nature make it harder for users to remember, leading to bad practices. In addition, composition requirements provide no defense against common attack types such as social engineering or insecure storage of passwords.",
+ "ImpactStatement": "",
+ "RemediationProcedure": "1. Go to Identity Domains: [https://cloud.oracle.com/identity/domains/](https://cloud.oracle.com/identity/domains/)1. Select the Compartment the Domain to remediate is in1. Click on the Domain to remediate1. Click on Settings1. Click on Password policy to remediate1. Click Edit password rules1. Update the `Password length (minimum)` setting to 14 or greater6. Under The `Passwords must meet the following character requirements` section, update the number given in `Special (minimum)` setting to `1` or greateror Under The `Passwords must meet the following character requirements` section, update the number given in `Numeric (minimum)` setting to `1` or greater7. Click `Save changes`",
+ "AuditProcedure": "1. Go to Identity Domains: [https://cloud.oracle.com/identity/domains/](https://cloud.oracle.com/identity/domains/)1. Select the `Compartment` your Domain to review is in1. Click on the Domain to review1. Click on `Settings`1. Click on `Password policy`1. Click each Password policy in the domain1. Ensure `Password length (minimum)` is greater than or equal to 141. Under The `The following criteria apply to passwords` section, ensure that the number given in `Numeric (minimum)` setting is `1`, or the `Special (minimum)` setting is `1`.The following criteria apply to passwords:6. Ensure that 1 or more is selected for `Numeric (minimum)` OR `Special (minimum)`**From Cloud Guard:**To Enable Cloud Guard Auditing:Ensure Cloud Guard is enabled in the root compartment of the tenancy. For more information about enabling Cloud Guard, please look at the instructions included in Ensure Cloud Guard is enabled in the root compartment of the tenancy Recommendation in the Logging and Monitoring section. **From Console:**1. Type `Cloud Guard` into the Search box at the top of the Console.2. Click `Cloud Guard` from the “Services” submenu.3. Click `Detector Recipes` in the Cloud Guard menu.4. Click `OCI Configuration Detector Recipe (Oracle Managed)` under the Recipe Name column.5. Find Password policy does not meet complexity requirements in the Detector Rules column.6. Select the vertical ellipsis icon and chose `Edit` on the Password policy does not meet complexity requirements row.7. In the Edit Detector Rule window, find the Input Setting box and verify/change the Required password length setting to 14.8. Click the `Save` button.**From CLI:**1. Update the Password policy does not meet complexity requirements Detector Rule in Cloud Guard to generate Problems if IAM password policy isn’t configured to enforce a password length of at least 14 characters with the following command:```oci cloud-guard detector-recipe-detector-rule update --detector-recipe-id --detector-rule-id PASSWORD_POLICY_NOT_COMPLEX --details '{configurations:[{ configKey : passwordPolicyMinLength, name : Required password length, value : 14, dataType : null, values : null }]}'```",
+ "AdditionalInformation": "The Audit Procedure and Remediation Procedure for OCI IAM without Identity Domains can be found in the CIS OCI Foundation Benchmark 2.0.0 under the respective recommendations.",
+ "References": "https://www.cisecurity.org/white-papers/cis-password-policy-guide/"
+ }
+ ]
+ },
+ {
+ "Id": "1.5",
+ "Description": "Ensure IAM password policy expires passwords within 365 days",
+ "Checks": [
+ "identity_password_policy_expires_within_365_days"
+ ],
+ "Attributes": [
+ {
+ "Section": "1. Identity and Access Management",
+ "Profile": "Level 1",
+ "AssessmentStatus": "Manual",
+ "Description": "IAM password policies can require passwords to be rotated or expired after a given number of days. It is recommended that the password policy expire passwords after 365 and are changed immediately based on events.",
+ "RationaleStatement": "Excessive password expiration requirements do more harm than good, because these requirements make users select predictable passwords, composed of sequential words and numbers that are closely related to each other. In these cases, the next password can be predicted based on the previous one (incrementing a number used in the password for example). Also, password expiration requirements offer no containment benefits because attackers will often use credentials as soon as they compromise them. Instead, immediate password changes should be based on key events including, but notlimited to:1. Indication of compromise1. Change of user roles1. When a user leaves the organization.Not only does changing passwords every few weeks or months frustrate the user, it's been suggested that it does more harm than good, because it could lead to bad practices by the user such as adding a character to the end of their existing password.In addition, we also recommend a yearly password change. This is primarily because for all their good intentions users will share credentials across accounts. Therefore, even if a breach is publicly identified, the user may not see this notification, or forget they have an account on that site. This could leave a shared credential vulnerable indefinitely. Having an organizational policy of a 1-year (annual) password expiration is a reasonable compromise to mitigate this with minimal user burden.",
+ "ImpactStatement": "",
+ "RemediationProcedure": "1. Go to Identity Domains: [https://cloud.oracle.com/identity/domains/](https://cloud.oracle.com/identity/domains/)1. Select the `Compartment` the Domain to remediate is in1. Click on the Domain to remediate1. Click on `Settings`1. Click on `Password policy` to remediate1. Click `Edit password rules`1. Change `Expires after (days)` to 365",
+ "AuditProcedure": "1. Go to Identity Domains: [https://cloud.oracle.com/identity/domains/](https://cloud.oracle.com/identity/domains/)1. Select the `Compartment` your Domain to review is in1. Click on the Domain to review1. Click on `Settings`1. Click on `Password policy`1. Click each Password policy in the domain1. Ensure `Expires after (days)` is less than or equal to 365 days",
+ "AdditionalInformation": "The Audit Procedure and Remediation Procedure for OCI IAM without Identity Domains can be found in the CIS OCI Foundation Benchmark 2.0.0 under the respective recommendations.",
+ "References": "https://www.cisecurity.org/white-papers/cis-password-policy-guide/"
+ }
+ ]
+ },
+ {
+ "Id": "1.6",
+ "Description": "Ensure IAM password policy prevents password reuse",
+ "Checks": [
+ "identity_password_policy_prevents_reuse"
+ ],
+ "Attributes": [
+ {
+ "Section": "1. Identity and Access Management",
+ "Profile": "Level 1",
+ "AssessmentStatus": "Manual",
+ "Description": "IAM password policies can prevent the reuse of a given password by the same user. It is recommended the password policy prevent the reuse of passwords.",
+ "RationaleStatement": "Enforcing password history ensures that passwords are not reused in for a certain period of time by the same user. If a user is not allowed to use last 24 passwords, that window of time is greater. This helps maintain the effectiveness of password security.",
+ "ImpactStatement": "",
+ "RemediationProcedure": "1. Go to Identity Domains: [https://cloud.oracle.com/identity/domains/](https://cloud.oracle.com/identity/domains/)1. Select the Compartment the Domain to remediate is in1. Click on the Domain to remediate1. Click on Settings1. Click on Password policy to remediate1. Click Edit password rules1. Update the number of remembered passwords in `Previous passwords remembered` setting to 24 or greater.",
+ "AuditProcedure": "1. Go to Identity Domains: [https://cloud.oracle.com/identity/domains/](https://cloud.oracle.com/identity/domains/)1. Select the `Compartment` your Domain to review is in1. Click on the Domain to review1. Click on `Settings`1. Click on `Password policy`1. Click each Password policy in the domain1. Ensure `Previous passwords remembered` is set 24 or greater",
+ "AdditionalInformation": "The Audit Procedure and Remediation Procedure for OCI IAM without Identity Domains can be found in the CIS OCI Foundation Benchmark 2.0.0 under the respective recommendations.",
+ "References": ""
+ }
+ ]
+ },
+ {
+ "Id": "1.7",
+ "Description": "Ensure MFA is enabled for all users with a console password",
+ "Checks": [
+ "identity_user_mfa_enabled_console_access"
+ ],
+ "Attributes": [
+ {
+ "Section": "1. Identity and Access Management",
+ "Profile": "Level 1",
+ "AssessmentStatus": "Automated",
+ "Description": "Multi-factor authentication is a method of authentication that requires the use of more than one factor to verify a user’s identity.With MFA enabled in the IAM service, when a user signs in to Oracle Cloud Infrastructure, they are prompted for their user name and password, which is the first factor (something that they know). The user is then prompted to provide a verification code from a registered MFA device, which is the second factor (something that they have). The two factors work together, requiring an extra layer of security to verify the user’s identity and complete the sign-in process.OCI IAM supports two-factor authentication using a password (first factor) and a device that can generate a time-based one-time password (TOTP) (second factor).See [OCI documentation](https://docs.cloud.oracle.com/en-us/iaas/Content/Identity/Tasks/usingmfa.htm) for more details.",
+ "RationaleStatement": "Multi factor authentication adds an extra layer of security during the login process and makes it harder for unauthorized users to gain access to OCI resources.",
+ "ImpactStatement": "",
+ "RemediationProcedure": "Each user must enable MFA for themselves using a device they will have access to every time they sign in. An administrator cannot enable MFA for another user but can enforce MFA by identifying the list of non-complaint users, notifying them or disabling access by resetting the password for non-complaint accounts.**Disabling access from Console:**1. Go to [https://cloud.oracle.com/identity/](https://cloud.oracle.com/identity/).1. Select `Domains` from Identity menu.1. Select the domain1. Click `Security`1. Click `Sign-on polices` then the `Default Sign-on Policy`1. Under the sign-on rules header, click the three dots on the rule with the highest priority.1. Select `Edit sign-on rule`1. Make a change to ensure that `allow access` is selected and `prompt for an additional factor` is enabled",
+ "AuditProcedure": "**From Console:**1. Go to Identity Domains: [https://cloud.oracle.com/identity/domains/](https://cloud.oracle.com/identity/domains/)1. Select the `Compartment` your Domain to review is in1. Click on the Domain to review1. Click on `Security`1. Click `Sign-on policies` 1. Select the sign-on policy to review6. Under the sign-on rules header, click the three dots on the rule with the highest priority.7. Select `Edit sign-on rule`8. Verify that `allow access` is selected and `prompt for an additional factor` is enabled* This requires users to enable MFA when they next login next however, to determine users have enabled MFA use the below CLI.**From the CLI:*** This CLI command checks which users have enabled MFA for their accounts1. Execute the below:```tenancy_ocid=`oci iam compartment list --raw-output --query data[?contains(\\compartment-id\\,'.tenancy.')].\\compartment-id\\ | [0]`for id_domain_url in `oci iam domain list --compartment-id $tenancy_ocid --all | jq -r '.data[] | .url'`do oci identity-domains users list --endpoint $id_domain_url 2>/dev/null | jq -r '.data.resources[] | select(.urn-ietf-params-scim-schemas-oracle-idcs-extension-mfa-user.mfa-status!=ENROLLED)' 2>/dev/null | jq -r '.ocid'donefor region in `oci iam region-subscription list | jq -r '.data[] | .region-name'`; do for compid in `oci iam compartment list --compartment-id-in-subtree TRUE --all 2>/dev/null | jq -r '.data[] | .id'` do for id_domain_url in `oci iam domain list --compartment-id $compid --region $region --all 2>/dev/null | jq -r '.data[] | .url'` do oci identity-domains users list --endpoint $id_domain_url 2>/dev/null | jq -r '.data.resources[] | select(.urn-ietf-params-scim-schemas-oracle-idcs-extension-mfa-user.mfa-status!=ENROLLED)' 2>/dev/null | jq -r '.ocid' done done done```2. Ensure no results are returned",
+ "AdditionalInformation": "The Audit Procedure and Remediation Procedure for OCI IAM without Identity Domains can be found in the CIS OCI Foundation Benchmark 2.0.0 under the respective recommendations.",
+ "References": "https://docs.cloud.oracle.com/en-us/iaas/Content/Identity/Tasks/usingmfa.htm:https://docs.oracle.com/en-us/iaas/Content/Security/Reference/iam_security_topic-IAM_MFA.htm"
+ }
+ ]
+ },
+ {
+ "Id": "1.8",
+ "Description": "Ensure user API keys rotate within 90 days",
+ "Checks": [
+ "identity_user_api_keys_rotated_90_days"
+ ],
+ "Attributes": [
+ {
+ "Section": "1. Identity and Access Management",
+ "Profile": "Level 1",
+ "AssessmentStatus": "Automated",
+ "Description": "API keys are used by administrators, developers, services and scripts for accessing OCI APIs directly or via SDKs/OCI CLI to search, create, update or delete OCI resources.The API key is an RSA key pair. The private key is used for signing the API requests and the public key is associated with a local or synchronized user's profile.",
+ "RationaleStatement": "It is important to secure and rotate an API key every 90 days or less as it provides the same level of access that a user it is associated with has.In addition to a security engineering best practice, this is also a compliance requirement. For example, PCI-DSS Section 3.6.4 states, Verify that key-management procedures include a defined cryptoperiod for each key type in use and define a process for key changes at the end of the defined crypto period(s).",
+ "ImpactStatement": "",
+ "RemediationProcedure": "**From Console:**1. Login to OCI Console.2. Select `Identity & Security` from the Services menu.3. Select `Domains` from the Identity menu.4. For each domain listed, click on the name and select `Users`.5. Click on an individual user under the Name heading.6. Click on `API Keys` in the lower left-hand corner of the page.7. Delete any API Keys that are older than 90 days under the `Created` column of the API Key table.**From CLI:**```oci iam user api-key delete --user-id __ --fingerprint ```",
+ "AuditProcedure": "**From Console:**1. Login to OCI Console.2. Select `Identity & Security` from the Services menu.3. Select `Domains` from the Identity menu.4. For each domain listed, click on the name and select `Users`.5. Click on an individual user under the Name heading.6. Click on `API Keys` in the lower left-hand corner of the page.7. Ensure the date of the API key under the `Created` column of the API Key is no more than 90 days old.",
+ "AdditionalInformation": "The Audit Procedure and Remediation Procedure for OCI IAM without Identity Domains can be found in the CIS OCI Foundation Benchmark 2.0.0 under the respective recommendations.",
+ "References": ""
+ }
+ ]
+ },
+ {
+ "Id": "1.9",
+ "Description": "Ensure user customer secret keys rotate within 90 days",
+ "Checks": [
+ "identity_user_customer_secret_keys_rotated_90_days"
+ ],
+ "Attributes": [
+ {
+ "Section": "1. Identity and Access Management",
+ "Profile": "Level 1",
+ "AssessmentStatus": "Automated",
+ "Description": "Object Storage provides an API to enable interoperability with Amazon S3. To use this Amazon S3 Compatibility API, you need to generate the signing key required to authenticate with Amazon S3.This special signing key is an Access Key/Secret Key pair. Oracle generates the Customer Secret key to pair with the Access Key.",
+ "RationaleStatement": "It is important to rotate customer secret keys at least every 90 days, as they provide the same level of object storage access that the user they are associated with has.",
+ "ImpactStatement": "",
+ "RemediationProcedure": "**From Console:**1. Login to OCI Console.1. Select `Identity & Security` from the Services menu.1. Select Domains from the Identity menu.1. For each domain listed, click on the name and select `Users`.1. Click on an individual user under the `Username` heading.1. Click on `Customer Secret Keys` in the lower left-hand corner of the page.1. Delete any Access Keys with a date older than 90 days under the `Created` column of the Customer Secret Keys.",
+ "AuditProcedure": "**From Console:**1. Login to OCI Console.1. Select `Identity & Security` from the Services menu.1. Select Domains from the Identity menu.1. For each domain listed, click on the name and select `Users`.1. Click on an individual user under the `Username` heading.1. Click on `Customer Secret Keys` in the lower left-hand corner of the page.1. Ensure the date of the Customer Secret Key under the `Created` column of the Customer Secret Key is no more than 90 days old.",
+ "AdditionalInformation": "The Audit Procedure and Remediation Procedure for OCI IAM without Identity Domains can be found in the CIS OCI Foundation Benchmark 2.0.0 under the respective recommendations.",
+ "References": ""
+ }
+ ]
+ },
+ {
+ "Id": "1.10",
+ "Description": "Ensure user auth tokens rotate within 90 days",
+ "Checks": [
+ "identity_user_auth_tokens_rotated_90_days"
+ ],
+ "Attributes": [
+ {
+ "Section": "1. Identity and Access Management",
+ "Profile": "Level 1",
+ "AssessmentStatus": "Automated",
+ "Description": "Auth tokens are authentication tokens generated by Oracle. You use auth tokens to authenticate with APIs that do not support the Oracle Cloud Infrastructure signature-based authentication. If the service requires an auth token, the service-specific documentation instructs you to generate one and how to use it.",
+ "RationaleStatement": "It is important to secure and rotate an auth token every 90 days or less as it provides the same level of access to APIs that do not support the OCI signature-based authentication as the user associated to it.",
+ "ImpactStatement": "",
+ "RemediationProcedure": "**From Console:**1. Login to OCI Console.1. Select `Identity & Security` from the Services menu.1. Select Domains from the Identity menu.1. For each domain listed, click on the name and select `Users`.1. Click on an individual user under the `Username` heading.1. Click on `Auth Tokens` in the lower left-hand corner of the page.1. Delete any auth token with a date older than 90 days under the `Created` column of the Customer Secret Keys.",
+ "AuditProcedure": "**From Console:**1. Login to OCI Console.1. Select `Identity & Security` from the Services menu.1. Select Domains from the Identity menu.1. For each domain listed, click on the name and select `Users`.1. Click on an individual user under the `Username` heading.5. Click on `Auth Tokens` in the lower left-hand corner of the page.1. Ensure the date of the Auth Token under the `Created` column of the Customer Secret Key is no more than 90 days old.",
+ "AdditionalInformation": "The Audit Procedure and Remediation Procedure for OCI IAM without Identity Domains can be found in the CIS OCI Foundation Benchmark 2.0.0 under the respective recommendations.",
+ "References": ""
+ }
+ ]
+ },
+ {
+ "Id": "1.11",
+ "Description": "Ensure user IAM Database Passwords rotate within 90 days",
+ "Checks": [
+ "identity_user_db_passwords_rotated_90_days"
+ ],
+ "Attributes": [
+ {
+ "Section": "1. Identity and Access Management",
+ "Profile": "Level 1",
+ "AssessmentStatus": "Manual",
+ "Description": "Users can create and manage their database password in their IAM user profile and use that password to authenticate to databases in their tenancy. An IAM database password is a different password than an OCI Console password. Setting an IAM database password allows an authorized IAM user to sign in to one or more Autonomous Databases in their tenancy.An IAM database password is a different password than an OCI Console password. Setting an IAM database password allows an authorized IAM user to sign in to one or more Autonomous Databases in their tenancy.",
+ "RationaleStatement": "It is important to secure and rotate an IAM Database password 90 days or less as it provides the same access the user would have a using a local database user.",
+ "ImpactStatement": "",
+ "RemediationProcedure": "#### OCI IAM with Identity Domains**From Console:**1. Login to OCI Console.1. Select `Identity & Security` from the Services menu.1. Select Domains from the Identity menu.1. For each domain listed, click on the name and select `Users`.1. Click on an individual user under the `Username` heading.1. Click on `IAM Database Passwords` in the lower left-hand corner of the page.1. Delete any Database Passwords with a date older than 90 days under the `Created` column of the Database Passwords.",
+ "AuditProcedure": "**From Console:**1. Login to OCI Console.2. Select `Identity & Security` from the Services menu.3. Select `Users` from the Identity menu.4. Click on an individual user under the Name heading.5. Click on `Database Passwords` in the lower left-hand corner of the page.6. Ensure the date of the Database Passwords under the `Created` column of the Database Passwords is no more than 90 days **From Console:**1. Login to OCI Console.1. Select `Identity & Security` from the Services menu.1. Select Domains from the Identity menu.1. For each domain listed, click on the name and select `Users`.1. Click on an individual user under the `Username` heading.1. Click on `Database Passwords` in the lower left-hand corner of the page.1. Ensure the date of the Database Passwords under the `Created` column of the Database Password is no more than 90 days old.",
+ "AdditionalInformation": "The Audit Procedure and Remediation Procedure for OCI IAM without Identity Domains can be found in the CIS OCI Foundation Benchmark 2.0.0 under the respective recommendations.",
+ "References": "https://docs.oracle.com/en-us/iaas/Content/Identity/Concepts/usercredentials.htm#usercredentials_iam_db_pwd"
+ }
+ ]
+ },
+ {
+ "Id": "1.12",
+ "Description": "Ensure API keys are not created for tenancy administrator users",
+ "Checks": [
+ "identity_tenancy_admin_users_no_api_keys"
+ ],
+ "Attributes": [
+ {
+ "Section": "1. Identity and Access Management",
+ "Profile": "Level 1",
+ "AssessmentStatus": "Automated",
+ "Description": "Tenancy administrator users have full access to the organization's OCI tenancy. API keys associated with user accounts are used for invoking the OCI APIs via custom programs or clients like CLI/SDKs. The clients are typically used for performing day-to-day operations and should never require full tenancy access. Service-level administrative users with API keys should be used instead.",
+ "RationaleStatement": "For performing day-to-day operations tenancy administrator access is not needed.Service-level administrative users with API keys should be used to apply privileged security principle.",
+ "ImpactStatement": "",
+ "RemediationProcedure": "**From Console:**1. Login to OCI console.2. Select `Identity` from Services menu.3. Select `Users` from Identity menu, or select `Domains`, select a domain, and select `Users`.4. Select the username of a tenancy administrator user with an API key.5. Select `API Keys` from the menu in the lower left-hand corner.6. Delete any associated keys from the `API Keys` table.7. Repeat steps 3-6 for all tenancy administrator users with an API key.**From CLI:**1. For each tenancy administrator user with an API key, execute the following command to retrieve API key details:```oci iam user api-key list --user-id ```2. For each API key, execute the following command to delete the key:```oci iam user api-key delete --user-id --fingerprint ```3. The following message will be displayed:```Are you sure you want to delete this resource? [y/N]:```4. Type 'y' and press 'Enter'.",
+ "AuditProcedure": "**From Console:**1. Login to OCI Console. 1. Select `Identity & Security` from the Services menu.1. Select `Domains` from the Identity menu.1. Click on the 'Default' Domain in the (root).1. Click on 'Groups'.1. Select the 'Administrators' group by clicking on the Name1. Click on each local or synchronized `Administrators` member profile4. Click on API Keys to verify if a user has an API key associated.",
+ "AdditionalInformation": "The Audit Procedure and Remediation Procedure for OCI IAM without Identity Domains can be found in the CIS OCI Foundation Benchmark 2.0.0 under the respective recommendations.",
+ "References": ""
+ }
+ ]
+ },
+ {
+ "Id": "1.13",
+ "Description": "Ensure all OCI IAM local user accounts have a valid and current email address",
+ "Checks": [
+ "identity_user_valid_email_address"
+ ],
+ "Attributes": [
+ {
+ "Section": "1. Identity and Access Management",
+ "Profile": "Level 1",
+ "AssessmentStatus": "Manual",
+ "Description": "All OCI IAM local user accounts have an email address field associated with the account. It is recommended to specify an email address that is valid and current.If you have an email address in your user profile, you can use the Forgot Password link on the sign on page to have a temporary password sent to you.",
+ "RationaleStatement": "Having a valid and current email address associated with an OCI IAM local user account allows you to tie the account to identity in your organization. It also allows that user to reset their password if it is forgotten or lost.",
+ "ImpactStatement": "",
+ "RemediationProcedure": "**From Console:**1. Login to OCI Console.1. Select `Identity & Security` from the Services menu.1. Select Domains from the Identity menu.1. For each domain listed, click on the name and select `Users`.1. Click on each non-complaint user.1. Click on `Edit User`.1. Enter a valid and current email address in the Email and Recovery Email text boxes.1. Click `Save Changes`",
+ "AuditProcedure": "**From Console:**1. Login to OCI Console.1. Select `Identity & Security` from the Services menu.1. Select Domains from the Identity menu.1. For each domain listed, click on the name and select `Users`.1. Click on an individual user under the `Username` heading.1. Ensure a valid and current email address is next to Email and Recovery email.",
+ "AdditionalInformation": "The Audit Procedure and Remediation Procedure for OCI IAM without Identity Domains can be found in the CIS OCI Foundation Benchmark 2.0.0 under the respective recommendations.",
+ "References": ""
+ }
+ ]
+ },
+ {
+ "Id": "1.14",
+ "Description": "Ensure Instance Principal authentication is used for OCI instances, OCI Cloud Databases and OCI Functions to access OCI resources",
+ "Checks": [
+ "identity_instance_principal_used"
+ ],
+ "Attributes": [
+ {
+ "Section": "1. Identity and Access Management",
+ "Profile": "Level 1",
+ "AssessmentStatus": "Manual",
+ "Description": "OCI instances, OCI database and OCI functions can access other OCI resources either via an OCI API key associated to a user or via Instance Principal. Instance Principal authentication can be achieved by inclusion in a Dynamic Group that has an IAM policy granting it the required access or using an OCI IAM policy that has `request.principal` added to the `where` clause. Access to OCI Resources refers to making API calls to another OCI resource like Object Storage, OCI Vaults, etc.",
+ "RationaleStatement": "Instance Principal reduces the risks related to hard-coded credentials. Hard-coded API keys can be shared and require rotation, which can open them up to being compromised. Compromised credentials could allow access to OCI services outside of the expected radius.",
+ "ImpactStatement": "For an OCI instance that contains embedded credential audit the scripts and environment variables to ensure that none of them contain OCI API Keys or credentials.",
+ "RemediationProcedure": "**From Console (Dynamic Groups):**1. Go to [https://cloud.oracle.com/identity/domains/](https://cloud.oracle.com/identity/domains/)1. Select a Compartment1. Click on the Domain1. Click on `Dynamic groups`1. Click Create Dynamic Group.1. Enter a Name1. Enter a Description1. Enter Matching Rules to that includes the instances accessing your OCI resources.1. Click Create.",
+ "AuditProcedure": "**From Console (Dynamic Groups):**1. Go to [https://cloud.oracle.com/identity/domains/](https://cloud.oracle.com/identity/domains/)1. Select a Compartment1. Click on a Domain1. Click on `Dynamic groups`1. Click on the Dynamic Group1. Check if the Matching Rules includes the instances accessing your OCI resources.**From Console (request.principal):**1. Go to [https://cloud.oracle.com/identity/policies](https://cloud.oracle.com/identity/policies)1. Select a Compartment1. Click on an individual policy under the Name heading.1. Ensure Policy statements look like this :```allow any-user to in compartment where ALL {request.principal.type='', request.principal.id=''}```or```allow any-user to in compartment where ALL {request.principal.type='', request.principal.compartment.id=''}```**From CLI (request.principal):**1. Execute the following for each compartment_OCID: ```oci iam policy list --compartment-id | grep request.principal```1. Ensure that the condition includes the instances accessing your OCI resources",
+ "AdditionalInformation": "The Audit Procedure and Remediation Procedure for OCI IAM without Identity Domains can be found in the CIS OCI Foundation Benchmark 2.0.0 under the respective recommendations.",
+ "References": "https://docs.oracle.com/en-us/iaas/Content/Identity/Tasks/managingdynamicgroups.htm"
+ }
+ ]
+ },
+ {
+ "Id": "1.15",
+ "Description": "Ensure storage service-level admins cannot delete resources they manage",
+ "Checks": [],
+ "Attributes": [
+ {
+ "Section": "1. Identity and Access Management",
+ "Profile": "Level 2",
+ "AssessmentStatus": "Manual",
+ "Description": "To apply the separation of duties security principle, one can restrict service-level administrators from being able to delete resources they are managing. It means service-level administrators can only manage resources of a specific service but not delete resources for that specific service.Example policies for global/tenant level for block volume service-administrators:```Allow group VolumeUsers to manage volumes in tenancy where request.permission!='VOLUME_DELETE' Allow group VolumeUsers to manage volume-backups in tenancy where request.permission!='VOLUME_BACKUP_DELETE'```Example policies for global/tenant level for file storage system service-administrators:```Allow group FileUsers to manage file-systems in tenancy where request.permission!='FILE_SYSTEM_DELETE'Allow group FileUsers to manage mount-targets in tenancy where request.permission!='MOUNT_TARGET_DELETE'Allow group FileUsers to manage export-sets in tenancy where request.permission!='EXPORT_SET_DELETE'```Example policies for global/tenant level for object storage system service-administrators:```Allow group BucketUsers to manage objects in tenancy where request.permission!='OBJECT_DELETE' Allow group BucketUsers to manage buckets in tenancy where request.permission!='BUCKET_DELETE'```",
+ "RationaleStatement": "Creating service-level administrators without the ability to delete the resource they are managing helps in tightly controlling access to Oracle Cloud Infrastructure (OCI) services by implementing the separation of duties security principle.",
+ "ImpactStatement": "",
+ "RemediationProcedure": "**From Console:**1. Login to OCI console.2. Go to Identity -> Policies, In the compartment dropdown, choose the compartment. Open each policy to view the policy statements.3. Add the appropriate `where` condition to any policy statement that allows the storage service-level to manage the storage service.",
+ "AuditProcedure": "**From Console:**1. Login to OCI console.2. Go to Identity -> Policies, In the compartment dropdown, choose the compartment. 3. Open each policy to view the policy statements.4. Verify the policies to ensure that the policy statements that grant access to storage service-level administrators have a condition that excludes access to delete the service they are the administrator for.**From CLI:**1. Execute the following command:```for compid in `oci iam compartment list --compartment-id-in-subtree TRUE 2>/dev/null | jq -r '.data[] | .id'` do for policy in `oci iam policy list --compartment-id $compid 2>/dev/null | jq -r '.data[] | .id'` do output=`oci iam policy list --compartment-id $compid 2>/dev/null | jq -r '.data[] | .id, .name, .statements'` if [ ! -z $output ]; then echo $output; fi done done```2. Verify the policies to ensure that the policy statements that grant access to storage service-level administrators have a condition that excludes access to delete the service they are the administrator for.",
+ "AdditionalInformation": "",
+ "References": "https://docs.oracle.com/en/solutions/oci-best-practices/protect-data-rest1.html#GUID-939A5EA1-3057-48E0-9E02-ADAFCB82BA3E:https://docs.oracle.com/en-us/iaas/Content/Identity/policyreference/policyreference.htm:https://docs.oracle.com/en-us/iaas/Content/Block/home.htm:https://docs.oracle.com/en-us/iaas/Content/File/home.htm:https://docs.oracle.com/en-us/iaas/Content/Object/home.htm"
+ }
+ ]
+ },
+ {
+ "Id": "1.16",
+ "Description": "Ensure OCI IAM credentials unused for 45 days or more are disabled",
+ "Checks": [],
+ "Attributes": [
+ {
+ "Section": "1. Identity and Access Management",
+ "Profile": "Level 1",
+ "AssessmentStatus": "Automated",
+ "Description": "OCI IAM Local users can access OCI resources using different credentials, such as passwords or API keys. It is recommended that credentials that have been unused for 45 days or more be deactivated or removed.",
+ "RationaleStatement": "Disabling or removing unnecessary OCI IAM local users will reduce the window of opportunity for credentials associated with a compromised or abandoned account to be used.",
+ "ImpactStatement": "",
+ "RemediationProcedure": "**From Console:**1. Login to OCI Console.2. Select `Identity & Security` from the Services menu.3. Select Domains from the Identity menu.4. For each domain listed, click on the name and select `Users`.5. Click on an individual user under the `Username` heading.6. Click `More action`7. Select `Deactivate`**From CLI:**1. Create a input.json:```{ operations: [ { op: replace, path: active,value: false} ], schemas: [urn:ietf:params:scim:api:messages:2.0:PatchOp], userId: }```2. Execute the below:```oci identity-domains user patch --from-json file://file.json --endpoint ```",
+ "AuditProcedure": "Perform the following to determine if unused credentials exist:**From Console:**For Passwords:1. Login to OCI Console.2. Select `Identity & Security` from the Services menu.3. Select `Domains` from the `Identity` menu.4. For each domain listed, click on the name 5. Click `Reports`6. Under Dormant users report click `View report`7. Enter a date 45 days from today’s date in Last Successful Login Date8. Check and ensure that `Last Successful Login Date` is greater than 45 days or emptyFor API Keys:1. Login to OCI Console.2. Select `Observability & Management` from the Services menu.3. Select `Search` from `Logging` menu4. Click `Show Advanced Mode` in the right corner5. Select `Custom` from `Filter by time`6. Under `Select regions to search` add regions7. Under `Query` enter the following query in the text box:```search /_Audit_Include_Subcompartment | data.identity.credentials='//' | summarize count() by data.identity.principalId```8. Enter a day range - Note each query can only be 14 days multiple queries will be required to go 45 days9. Click `Search`10. Expand the results11. If results the count is not zero the user has used their API key during that period12. Repeat steps 8 – 11 for the 45-day period**From CLI:**For Passwords:1. Execute the below:```oci identity-domains users list --all --endpoint --attributes urn:ietf:params:scim:schemas:oracle:idcs:extension:userState:User:lastSuccessfulLoginDate --profile Oracle --query '.data.resources[]|.user-name + + .urn-ietf-params-scim-schemas-oracle-idcs-extension-user-state-user.last-successful-login-date'```2. Review the output the that the date is under 45 days, or no date means they have not logged inFor API Keys: 1. Create the search query text:```export query=search \\/_Audit_Include_Subcompartment\\ | data.identity.credentials='*' | summarize count() by data.identity.principalId```2. Select a day range. Date format is `2024-12-01`- Note each query can only be 14 days multiple queries will be required to go 45 days3. Execute the below:```oci logging-search search-logs --search-query $query --time-start --time-end --query 'data.results[0].data.count' export query=search \\/_Audit_Include_Subcompartment\\ | data.identity.credentials='*' | summarize count() by data.identity.principalId```4. If results the count is not zero, the user has used their API key during that period5. Repeat steps 2 – 4 for the 45-day period",
+ "AdditionalInformation": "This audit should exclude the OCI Administrator, break-glass accounts, and service accounts as these accounts should only be used for day-to-day business and would likely be unused for up to 45 days.",
+ "References": ""
+ }
+ ]
+ },
+ {
+ "Id": "1.17",
+ "Description": "Ensure there is only one active API Key for any single OCI IAM user",
+ "Checks": [],
+ "Attributes": [
+ {
+ "Section": "1. Identity and Access Management",
+ "Profile": "Level 1",
+ "AssessmentStatus": "Automated",
+ "Description": "API Keys are long-term credentials for an OCI IAM user. They can be used to make programmatic requests to the OCI APIs directly or via, OCI SDKs or the OCI CLI.",
+ "RationaleStatement": "Having a single API Key for an OCI IAM reduces attack surface area and makes it easier to manage.",
+ "ImpactStatement": "Deletion of an OCI API Key will remove programmatic access to OCI APIs",
+ "RemediationProcedure": "**From Console:**1. Login to OCI Console.2. Select `Identity & Security` from the Services menu.3. Select `Domains` from the Identity menu.4. For each domain listed, click on the name and select Users.5. Click on an individual user under the Name heading.6. Click on `API Keys` in the lower left-hand corner of the page.7. Delete one of the API Keys **From CLI:**1. Follow the audit procedure above.2. For API Key ID to be removed execute the following command:```oci identity-domains api-key delete –api-key-id --endpoint ```",
+ "AuditProcedure": "**From Console:**1. Login to OCI Console.2. Select `Identity & Security` from the Services menu.3. Select `Users` from the Identity menu.4. Click on an individual user under the Name heading.5. Click on `API Keys` in the lower left-hand corner of the page.6. Ensure the has only has a one API Key**From CLI:**1. Each user and in each Identity Domain```oci raw-request --http-method GET --target-uri https:///admin/v1/ApiKeys?filter=user.ocid+eq+%%22 | jq '.data.Resources[] | \\(.fingerprint) \\(.id)'```2. Ensure only one key is returned",
+ "AdditionalInformation": "",
+ "References": "https://docs.public.oneportal.content.oci.oraclecloud.com/en-us/iaas/Content/Security/Reference/iam_security_topic-IAM_Credentials.htm#IAM_Credentials"
+ }
+ ]
+ },
+ {
+ "Id": "2.1",
+ "Description": "Ensure no security lists allow ingress from 0.0.0.0/0 to port 22",
+ "Checks": [
+ "network_security_list_ingress_from_internet_to_ssh_port"
+ ],
+ "Attributes": [
+ {
+ "Section": "2. Networking",
+ "Profile": "Level 1",
+ "AssessmentStatus": "Automated",
+ "Description": "Security lists provide stateful and stateless filtering of ingress and egress network traffic to OCI resources on a subnet level. It is recommended that no security list allows unrestricted ingress access to port 22.",
+ "RationaleStatement": "Removing unfettered connectivity to remote console services, such as Secure Shell (SSH), reduces a server's exposure to risk.",
+ "ImpactStatement": "For updating an existing environment, care should be taken to ensure that administrators currently relying on an existing ingress from 0.0.0.0/0 have access to ports 22 and/or 3389 through another network security group or security list.",
+ "RemediationProcedure": "**From Console:**1. Follow the audit procedure above.2. For each security list in the returned results, click the security list name3. Either edit the `ingress rule` to be more restrictive, delete the `ingress rule` or click on the `VCN` and terminate the `security list` as appropriate.**From CLI:**1. Follow the audit procedure.2. For each of the `security lists` identified, execute the following command:```oci network security-list get --security-list-id ```3. Then either: - Update the `security list` by copying the `ingress-security-rules` element from the JSON returned by the above command, edit it appropriately and use it in the following command:```oci network security-list update --security-list-id --ingress-security-rules ''``` or - Delete the security list with the following command:```oci network security-list delete --security-list-id ```",
+ "AuditProcedure": "**From Console:**1. Login to the OCI Console.2. Click the search bar at the top of the screen.3. Type `Advanced Resource Query` and hit `enter`.4. Click the `Advanced Resource Query` button in the upper right corner of the screen.5. Enter the following query in the query box:```query SecurityList resources where (IngressSecurityRules.source = '0.0.0.0/0' && IngressSecurityRules.protocol = 6 && IngressSecurityRules.tcpOptions.destinationPortRange.max >= 22 && IngressSecurityRules.tcpOptions.destinationPortRange.min =<= 22) ```6. Ensure the query returns no results.**From CLI:**1. Execute the following command:```oci search resource structured-search --query-text query SecurityList resources where (IngressSecurityRules.source = '0.0.0.0/0' && IngressSecurityRules.protocol = 6 && IngressSecurityRules.tcpOptions.destinationPortRange.max >= 22 && IngressSecurityRules.tcpOptions.destinationPortRange.min <= 22) ```2. Ensure the query returns no results.**Cloud Guard**Ensure Cloud Guard is enabled in the root compartment of the tenancy. For more information about enabling Cloud Guard, please look at the instructions included in Recommendation 3.15.**From Console:**1. Type `Cloud Guard` into the Search box at the top of the Console.2. Click `Cloud Guard` from the “Services” submenu.3. Click `Detector Recipes` in the Cloud Guard menu.4. Click `OCI Configuration Detector Recipe (Oracle Managed)` under the Recipe Name column.5. Find VCN Security list allows traffic to non-public port from all sources (0.0.0.0/0) in the Detector Rules column.6. Select the vertical ellipsis icon and chose Edit on the VCN Security list allows traffic to non-public port from all sources (0.0.0.0/0) row.7. In the Edit Detector Rule window find the Input Setting box and verify/add to the Restricted Protocol: Ports List setting to TCP:[22], UDP:[22].8. Click the `Save` button.**From CLI:**1. Update the VCN Security list allows traffic to non-public port from all sources (0.0.0.0/0) Detector Rule in Cloud Guard to generate Problems if a VCN security list allows public access via port 22 with the following command:```oci cloud-guard detector-recipe-detector-rule update --detector-recipe-id --detector-rule-id SECURITY_LISTS_OPEN_SOURCE --details '{configurations:[{ configKey : securityListsOpenSourceConfig, name : Restricted Protocol:Ports List, value : TCP:[22], UDP:[22], dataType : null, values : null }]}'```",
+ "AdditionalInformation": "",
+ "References": ""
+ }
+ ]
+ },
+ {
+ "Id": "2.2",
+ "Description": "Ensure no security lists allow ingress from 0.0.0.0/0 to port 3389",
+ "Checks": [
+ "network_security_list_ingress_from_internet_to_rdp_port"
+ ],
+ "Attributes": [
+ {
+ "Section": "2. Networking",
+ "Profile": "Level 1",
+ "AssessmentStatus": "Automated",
+ "Description": "Security lists provide stateful and stateless filtering of ingress and egress network traffic to OCI resources on a subnet level. It is recommended that no security group allows unrestricted ingress access to port 3389.",
+ "RationaleStatement": "Removing unfettered connectivity to remote console services, such as Remote Desktop Protocol (RDP), reduces a server's exposure to risk.",
+ "ImpactStatement": "For updating an existing environment, care should be taken to ensure that administrators currently relying on an existing ingress from 0.0.0.0/0 have access to ports 22 and/or 3389 through another network security group or security list.",
+ "RemediationProcedure": "**From Console:**1. Follow the audit procedure above.2. For each security list in the returned results, click the security list name3. Either edit the `ingress rule` to be more restrictive, delete the `ingress rule` or click on the `VCN` and terminate the `security list` as appropriate.**From CLI:**1. Follow the audit procedure.2. For each of the `security lists` identified, execute the following command:```oci network security-list get --security-list-id ```3. Then either: - Update the `security list` by copying the `ingress-security-rules` element from the JSON returned by the above command, edit it appropriately, and use it in the following command```oci network security-list update --security-list-id --ingress-security-rules ''``` or - Delete the security list with the following command:```oci network security-list delete --security-list-id ```",
+ "AuditProcedure": "**From Console:**1. Login into the OCI Console2. Click in the search bar at the top of the screen.3. Type `Advanced Resource Query` and hit `enter`.4. Click the `Advanced Resource Query` button in the upper right corner of the screen.5. Enter the following query in the query box:```query SecurityList resources where (IngressSecurityRules.source = '0.0.0.0/0' && IngressSecurityRules.protocol = 6 && IngressSecurityRules.tcpOptions.destinationPortRange.max >= 3389 && IngressSecurityRules.tcpOptions.destinationPortRange.min <= 3389) ```6. Ensure query returns no results.**From CLI:**1. Execute the following command:```oci search resource structured-search --query-text query SecurityList resources where (IngressSecurityRules.source = '0.0.0.0/0' && IngressSecurityRules.protocol = 6 && IngressSecurityRules.tcpOptions.destinationPortRange.max >= 3389 && IngressSecurityRules.tcpOptions.destinationPortRange.min <= 3389) ```2. Ensure query returns no results.**Cloud Guard**To Enable Cloud Guard Auditing:Ensure Cloud Guard is enabled in the root compartment of the tenancy. For more information about enabling Cloud Guard, please look at the instructions included in Recommendation 3.15. **From Console:**1. Type `Cloud Guard` into the Search box at the top of the Console .2. Click `Cloud Guard` from the “Services” submenu.3. Click `Detector Recipes` in the Cloud Guard menu.4. Click `OCI Configuration Detector Recipe (Oracle Managed)` under the Recipe Name column.5. Find VCN Security list allows traffic to non-public port from all sources (0.0.0.0/0) in the Detector Rules column.6. Select the vertical ellipsis icon and choose Edit on the VCN Security list allows traffic to non-public port from all sources (0.0.0.0/0) row.7. In the Edit Detector Rule window find the Input Setting box and verify/add to the Restricted Protocol: Ports List setting to TCP:[3389], UDP:[3389].8. Click the `Save` button.**From CLI:**1. Update the VCN Security list allows traffic to non-public port from all sources (0.0.0.0/0) Detector Rule in Cloud Guard to generate Problems if a VCN security list allows public access via port 3389 with the following command:```oci cloud-guard detector-recipe-detector-rule update --detector-recipe-id --detector-rule-id SECURITY_LISTS_OPEN_SOURCE --details '{configurations:[{ configKey : securityListsOpenSourceConfig, name : Restricted Protocol:Ports List, value : TCP:[3389], UDP:[3389], dataType : null, values : null }]}'```",
+ "AdditionalInformation": "This recommendation can also be audited programmatically using REST API https://docs.oracle.com/en-us/iaas/api/#/en/iaas/20160918/SecurityList/ListSecurityLists",
+ "References": ""
+ }
+ ]
+ },
+ {
+ "Id": "2.3",
+ "Description": "Ensure no network security groups allow ingress from 0.0.0.0/0 to port 22",
+ "Checks": [
+ "network_security_group_ingress_from_internet_to_ssh_port"
+ ],
+ "Attributes": [
+ {
+ "Section": "2. Networking",
+ "Profile": "Level 1",
+ "AssessmentStatus": "Automated",
+ "Description": "Network security groups provide stateful filtering of ingress/egress network traffic to OCI resources. It is recommended that no security group allows unrestricted ingress to port 22.",
+ "RationaleStatement": "Removing unfettered connectivity to remote console services, such as Secure Shell (SSH), reduces a server's exposure to risk.",
+ "ImpactStatement": "For updating an existing environment, care should be taken to ensure that administrators currently relying on an existing ingress from 0.0.0.0/0 have access to ports 22 and/or 3389 through another network security group or security list.",
+ "RemediationProcedure": "**From Console:** 1. Login into the OCI Console. 2. Click the search bar at the top of the screen. 3. Type Advanced Resource Query and hit enter. 4. Click the Advanced Resource Query button in the upper right corner of the screen. 5. Enter the following query in the query box: query networksecuritygroup resources where lifeCycleState = 'AVAILABLE' 6. For each of the network security groups in the returned results, click the name and inspect each of the security rules. 7. Remove all security rules with direction: Ingress, Source: 0.0.0.0/0, and Destination Port Range: 22.**From CLI:**Issue the following command and identify the security rule to remove.``` for region in `oci iam region list | jq -r '.data[] | .name'`; do for compid in `oci iam compartment list 2>/dev/null | jq -r '.data[] | .id'`; do for nsgid in `oci network nsg list --compartment-id $compid --region $region --all 2>/dev/null | jq -r '.data[] | .id'` do output=`oci network nsg rules list --nsg-id=$nsgid --all 2>/dev/null | jq -r '.data[] | select(.source == 0.0.0.0/0 and .direction == INGRESS and ((.tcp-options.destination-port-range.max >= 22 and .tcp-options.destination-port-range.min <= 22) or .tcp-options.destination-port-range == null))'` if [ ! -z $output ]; then echo NSGID=, $nsgid, Security Rules=, $output; fi done done done```- Remove the security rules```oci network nsg rules remove --nsg-id=```or- Update the security rules```oci network nsg rules update --nsg-id= --security-rules='[]'eg: oci network nsg rules update --nsg-id=ocid1.networksecuritygroup.oc1.iad.xxxxxxxxxxxxxxxxxxxxxx --security-rules='[{ description: null, destination: null, destination-type: null, direction: INGRESS, icmp-options: null, id: 709001, is-stateless: null, protocol: 6, source: 140.238.154.0/24, source-type: CIDR_BLOCK, tcp-options: { destination-port-range: { max: 22, min: 22 }, source-port-range: null }, udp-options: null }]'```",
+ "AuditProcedure": "**From Console:** 1. Login into the OCI Console. 2. Click the search bar at the top of the screen. 3. Type Advanced Resource Query and hit enter. 4. Click the Advanced Resource Query button in the upper right corner of the screen. 5. Enter the following query in the query box:```query networksecuritygroup resources where lifeCycleState = 'AVAILABLE'``` 6. For each of the network security groups in the returned results, click the name and inspect each of the security rules. 7. Ensure that there are no security rules with direction: Ingress, Source: 0.0.0.0/0, and Destination Port Range: 22.**From CLI:**Issue the following command, it should return no values.```for region in $(oci iam region-subscription list | jq -r '.data[] | .region-name') do echo Enumerating region $region for compid in $(oci iam compartment list --include-root --compartment-id-in-subtree TRUE 2>/dev/null | jq -r '.data[] | .id') do echo Enumerating compartment $compid for nsgid in $(oci network nsg list --compartment-id $compid --region $region --all 2>/dev/null | jq -r '.data[] | .id') do output=$(oci network nsg rules list --nsg-id=$nsgid --all 2>/dev/null | jq -r '.data[] | select(.source == 0.0.0.0/0 and .direction == INGRESS and ((.tcp-options.destination-port-range.max >= 22 and .tcp-options.destination-port-range.min <= 22) or .tcp-options.destination-port-range == null))') if [ ! -z $output ]; then echo NSGID: , $nsgid, Security Rules: , $output; fi done done done```**Cloud Guard:**To Enable Cloud Guard Auditing:Ensure Cloud Guard is enabled in the root compartment of the tenancy. For more information about enabling Cloud Guard, please look at the instructions included in Recommendation 3.15. **From Console:**1. Type `Cloud Guard` into the Search box at the top of the Console .2. Click `Cloud Guard` from the “Services” submenu.3. Click `Detector Recipes` in the Cloud Guard menu.4. Click `OCI Configuration Detector Recipe (Oracle Managed)` under the Recipe Name column.5. Find NSG ingress rule contains disallowed IP/port in the Detector Rules column.6. Select the vertical ellipsis icon and chose Edit on the NSG ingress rule contains disallowed IP/port row.7. In the Edit Detector Rule window find the Input Setting box and verify/add to the Restricted Protocol: Ports List setting to TCP:[22], UDP:[22].8. Click the `Save` button.**From CLI:**1. Update the NSG ingress rule contains disallowed IP/port Detector Rule in Cloud Guard to generate Problems if a network security group allows ingress network traffic to port 22 with the following command:```oci cloud-guard detector-recipe-detector-rule update --detector-recipe-id --detector-rule-id VCN_NSG_INGRESS_RULE_PORTS_CHECK --details '{configurations:[ {configKey : nsgIngressRuleDisallowedPortsConfig, name : Default disallowed ports, value : TCP:[22], UDP:[22], dataType : null, values : null }]}'```",
+ "AdditionalInformation": "",
+ "References": ""
+ }
+ ]
+ },
+ {
+ "Id": "2.4",
+ "Description": "Ensure no network security groups allow ingress from 0.0.0.0/0 to port 3389",
+ "Checks": [
+ "network_security_group_ingress_from_internet_to_rdp_port"
+ ],
+ "Attributes": [
+ {
+ "Section": "2. Networking",
+ "Profile": "Level 1",
+ "AssessmentStatus": "Automated",
+ "Description": "Network security groups provide stateful filtering of ingress/egress network traffic to OCI resources. It is recommended that no security group allows unrestricted ingress access to port 3389.",
+ "RationaleStatement": "Removing unfettered connectivity to remote console services, such as Remote Desktop Protocol (RDP), reduces a server's exposure to risk.",
+ "ImpactStatement": "For updating an existing environment, care should be taken to ensure that administrators currently relying on an existing ingress from 0.0.0.0/0 have access to ports 22 and/or 3389 through another network security group or security list.",
+ "RemediationProcedure": "**From CLI:**Using the details returned from the audit procedure either:- Remove the security rules```oci network nsg rules remove --nsg-id=```or- Update the security rules```oci network nsg rules update --nsg-id= --security-rules=eg: oci network nsg rules update --nsg-id=ocid1.networksecuritygroup.oc1.iad.xxxxxxxxxxxxxxxxxxxxxx --security-rules='[{ description: null, destination: null, destination-type: null, direction: INGRESS, icmp-options: null, id: 709001, is-stateless: null, protocol: 6, source: 140.238.154.0/24, source-type: CIDR_BLOCK, tcp-options: { destination-port-range: { max: 3389, min: 3389 }, source-port-range: null }, udp-options: null }]'```",
+ "AuditProcedure": "**From CLI:**Issue the following command, it should not return anything.``` for region in $(oci iam region-subscription list | jq -r '.data[] | .region-name') do echo Enumerating region $region for compid in $(oci iam compartment list --include-root --compartment-id-in-subtree TRUE 2>/dev/null | jq -r '.data[] | .id') do echo Enumerating compartment $compid for nsgid in $(oci network nsg list --compartment-id $compid --region $region --all 2>/dev/null | jq -r '.data[] | .id') do output=$(oci network nsg rules list --nsg-id=$nsgid --all 2>/dev/null | jq -r '.data[] | select(.source == 0.0.0.0/0 and .direction == INGRESS and ((.tcp-options.destination-port-range.max >= 3389 and .tcp-options.destination-port-range.min <= 3389) or .tcp-options.destination-port-range == null))') if [ ! -z $output ]; then echo NSGID: , $nsgid, Security Rules: , $output; fi done done done```**From Cloud Guard:**To Enable Cloud Guard Auditing:Ensure Cloud Guard is enabled in the root compartment of the tenancy. For more information about enabling Cloud Guard, please look at the instructions included in Recommendation 3.15. **From Console:**1. Type `Cloud Guard` into the Search box at the top of the Console.2. Click `Cloud Guard` from the “Services” submenu.3. Click `Detector Recipes` in the Cloud Guard menu.4. Click `OCI Configuration Detector Recipe (Oracle Managed)` under the Recipe Name column.5. Find NSG ingress rule contains disallowed IP/port in the Detector Rules column.6. Select the vertical ellipsis icon and chose Edit on the NSG ingress rule contains disallowed IP/port row.7. In the Edit Detector Rule window find the Input Setting box and verify/add to the Restricted Protocol: Ports List setting to TCP:[3389], UDP:[3389].8. Click the Save button.**From CLI:**1. Update the NSG ingress rule contains disallowed IP/port Detector Rule in Cloud Guard to generate Problems if a network security group allows ingress network traffic to port 3389 with the following command:```oci cloud-guard detector-recipe-detector-rule update --detector-recipe-id --detector-rule-id VCN_NSG_INGRESS_RULE_PORTS_CHECK --details '{configurations:[ {configKey : nsgIngressRuleDisallowedPortsConfig, name : Default disallowed ports, value : TCP:[3389], UDP:[3389], dataType : null, values : null }]}'```",
+ "AdditionalInformation": "",
+ "References": ""
+ }
+ ]
+ },
+ {
+ "Id": "2.5",
+ "Description": "Ensure the default security list of every VCN restricts all traffic except ICMP",
+ "Checks": [
+ "network_default_security_list_restricts_traffic"
+ ],
+ "Attributes": [
+ {
+ "Section": "2. Networking",
+ "Profile": "Level 1",
+ "AssessmentStatus": "Automated",
+ "Description": "A default security list is created when a Virtual Cloud Network (VCN) is created and attached to the public subnets in the VCN. Security lists provide stateful or stateless filtering of ingress and egress network traffic to OCI resources in the VCN. It is recommended that the default security list does not allow unrestricted ingress and egress access to resources in the VCN.",
+ "RationaleStatement": "Removing unfettered connectivity to OCI resource, reduces a server's exposure to unauthorized access or data exfiltration.",
+ "ImpactStatement": "For updating existing environments Ingress rules with a source of 0.0.0.0/0, ensure that the necessary access is available through another Network Security Group or Security List.For updating existing environments Egress rules with a destination of 0.0.0.0/0 for an existing environment, ensure egress is covered via another Network Security Group, Security List, or through the stateful nature of the ingress rule.",
+ "RemediationProcedure": "**From Console:**1. Login into the OCI Console2. Click on `Networking -> Virtual Cloud Networks` from the services menu3. For each VCN listed `Click on Security Lists`4. Click on `Default Security List for `5. Identify the Ingress Rule with 'Source 0.0.0.0/0'6. Either Edit the Security rule to restrict the source and/or port range or delete the rule.7. Identify the Egress Rule with 'Destination 0.0.0.0/0, All Protocols'8. Either Edit the Security rule to restrict the source and/or port range or delete the rule.",
+ "AuditProcedure": "**From Console:**1. Login into the OCI Console2. Click on `Networking -> Virtual Cloud Networks` from the services menu3. For each VCN listed `Click on Security Lists`4. Click on `Default Security List for `5. Verify that there is no Ingress rule with 'Source 0.0.0.0/0'6. Verify that there is no Egress rule with 'Destination 0.0.0.0/0, All Protocols'",
+ "AdditionalInformation": "",
+ "References": "https://docs.oracle.com/en-us/iaas/Content/Security/Reference/networking_security.htm#Securing_Networking_VCN_Load_Balancers_and_DNS"
+ }
+ ]
+ },
+ {
+ "Id": "2.6",
+ "Description": "Ensure Oracle Integration Cloud (OIC) access is restricted to allowed sources",
+ "Checks": [
+ "integration_instance_access_restricted"
+ ],
+ "Attributes": [
+ {
+ "Section": "2. Networking",
+ "Profile": "Level 1",
+ "AssessmentStatus": "Manual",
+ "Description": "Oracle Integration (OIC) is a complete, secure, but lightweight integration solution that enables you to connect your applications in the cloud. It simplifies connectivity between your applications and connects both your applications that live in the cloud and your applications that still live on premises. Oracle Integration provides secure, enterprise-grade connectivity regardless of the applications you are connecting or where they reside. OIC instances are created within an Oracle managed secure private network with each having a public endpoint. The capability to configure ingress filtering of network traffic to protect your OIC instances from unauthorized network access is included. It is recommended that network access to your OIC instances be restricted to your approved corporate IP Addresses or Virtual Cloud Networks (VCN)s.",
+ "RationaleStatement": "Restricting connectivity to OIC Instances reduces an OIC instance’s exposure to risk.",
+ "ImpactStatement": "When updating ingress filters for an existing environment, care should be taken to ensure that IP addresses and VCNs currently used by administrators, users, and services to access your OIC instances are included in the updated filters.",
+ "RemediationProcedure": "**From Console:**1. Follow the audit procedure above.2. For each OIC instance in the returned results, click the OIC Instance name3. Click `Network Access`4. Either edit the `Network Access` to be more restrictive **From CLI**1. Follow the audit procedure.2. Get the json input format using the below command:```oci integration integration-instance change-network-endpoint --generate-param-json-input```3.For each of the OIC Instances identified get its details.4.Update the `Network Access`, copy the `network-endpoint-details` element from the JSON returned by the above get call, edit it appropriately and use it in the following command```Oci integration integration-instance change-network-endpoint --id --from-json ''```",
+ "AuditProcedure": "**From Console:**1. Login into the OCI Console2. Click in the search bar, top of the screen.3. Type Advanced Resource Query and hit enter.4. Click the Advanced Resource Query button in the upper right of the screen.5. Enter the following query in the query box:```query integrationinstance resources```6. For each OIC Instance returned click on the link under `Display name`7. Click on `Network Access`8 .Ensure `Restrict Network Access` is selected and the IP Address/CIDR Block as well as Virtual Cloud Networks are correct9. Repeat for other subscribed regions**From CLI:**1. Execute the following command:```for region in `oci iam region list | jq -r '.data[] | .name'`; do for compid in `oci iam compartment list --compartment-id-in-subtree TRUE 2>/dev/null | jq -r '.data[] | .id'` do output=`oci integration integration-instance list --compartment-id $compid --region $region --all 2>/dev/null | jq -r '.data[] | select(.network-endpoint-details.network-endpoint-type == null)'` if [ ! -z $output ]; then echo $output; fi done done```2. Ensure `allowlisted-http-ips` and `allowed-http-vcns` are correct",
+ "AdditionalInformation": "",
+ "References": "https://docs.oracle.com/en/cloud/paas/integration-cloud/integrations-user/get-started-integration-cloud-service.html"
+ }
+ ]
+ },
+ {
+ "Id": "2.7",
+ "Description": "Ensure Oracle Analytics Cloud (OAC) access is restricted to allowed sources or deployed within a Virtual Cloud Network",
+ "Checks": [
+ "analytics_instance_access_restricted"
+ ],
+ "Attributes": [
+ {
+ "Section": "2. Networking",
+ "Profile": "Level 1",
+ "AssessmentStatus": "Manual",
+ "Description": "Oracle Analytics Cloud (OAC) is a scalable and secure public cloud service that provides a full set of capabilities to explore and perform collaborative analytics for you, your workgroup, and your enterprise. OAC instances provide ingress filtering of network traffic or can be deployed with in an existing Virtual Cloud Network VCN. It is recommended that all new OAC instances be deployed within a VCN and that the Access Control Rules are restricted to your corporate IP Addresses or VCNs for existing OAC instances.",
+ "RationaleStatement": "Restricting connectivity to Oracle Analytics Cloud instances reduces an OAC instance’s exposure to risk.",
+ "ImpactStatement": "When updating ingress filters for an existing environment, care should be taken to ensure that IP addresses and VCNs currently used by administrators, users, and services to access your OAC instances are included in the updated filters. Also, these changes will temporarily bring the OAC instance offline.",
+ "RemediationProcedure": "**From Console:**1. Follow the audit procedure above.2. For each OAC instance in the returned results, click the OAC Instance name3. Click `Edit` next to `Access Control Rules`4. Click `+Another Rule` and add rules as required**From CLI:**1. Follow the audit procedure.2. Get the json input format by executing the below command:```oci analytics analytics-instance change-network-endpoint --generate-full-command-json-input```3. For each of the OAC Instances identified get its details.4. Update the `Access Control Rules`, copy the `network-endpoint-details` element from the JSON returned by the above get call, edit it appropriately and use it in the following command:```oci integration analytics-instance change-network-endpoint --from-json ''```",
+ "AuditProcedure": "**From Console:**1 Login into the OCI Console2. Click in the search bar, top of the screen.3. Type Advanced Resource Query and hit enter.4. Click the Advanced Resource Query button in the upper right of the screen.5. Enter the following query in the query box:```query analyticsinstance resources```6. For each OAC Instance returned click on the link under `Display name`.7. Ensure `Access Control Rules` IP Address/CIDR Block as well as Virtual Cloud Networks are correct.8. Repeat for other subscribed regions.**From CLI:**1. Execute the following command:```for region in `oci iam region list | jq -r '.data[] | .name'`; do for compid in `oci iam compartment list --compartment-id-in-subtree TRUE 2>/dev/null | jq -r '.data[] | .id'` do output=`oci analytics analytics-instance list --compartment-id $compid --region $region --all 2>/dev/null | jq -r '.data[] | select(.network-endpoint-details.network-endpoint-type == PUBLIC)'` if [ ! -z $output ]; then echo $output; fi done done```2. Ensure `network-endpoint-type` are correct.",
+ "AdditionalInformation": "https://docs.oracle.com/en/cloud/paas/analytics-cloud/acoci/manage-service-access-and-security.html#GUID-3DB25824-4417-4981-9EEC-29C0C6FD3883",
+ "References": ""
+ }
+ ]
+ },
+ {
+ "Id": "2.8",
+ "Description": "Ensure Oracle Autonomous Shared Databases (ADB) access is restricted to allowed sources or deployed within a Virtual Cloud Network",
+ "Checks": [
+ "database_autonomous_database_access_restricted"
+ ],
+ "Attributes": [
+ {
+ "Section": "2. Networking",
+ "Profile": "Level 1",
+ "AssessmentStatus": "Manual",
+ "Description": "Oracle Autonomous Database Shared (ADB-S) automates database tuning, security, backups, updates, and other routine management tasks traditionally performed by DBAs. ADB-S provide ingress filtering of network traffic or can be deployed within an existing Virtual Cloud Network (VCN). It is recommended that all new ADB-S databases be deployed within a VCN and that the Access Control Rules are restricted to your corporate IP Addresses or VCNs for existing ADB-S databases.",
+ "RationaleStatement": "Restricting connectivity to ADB-S Databases reduces an ADB-S database’s exposure to risk.",
+ "ImpactStatement": "When updating ingress filters for an existing environment, care should be taken to ensure that IP addresses and VCNs currently used by administrators, users, and services to access your ADB-S instances are included in the updated filters.",
+ "RemediationProcedure": "**From Console:**1. Follow the audit procedure above.2. For each ADB-S database in the returned results, click the ADB-S database name3. Click `Edit` next to `Access Control Rules`4. Click `+Another Rule` and add rules as required5. Click `Save Changes`**From CLI:**1. Follow the audit procedure.2. Get the json input format by executing the following command:```oci db autonomous-database update --generate-full-command-json-input```3. For each of the ADB-S Database identified get its details.4. Update the `whitelistIps`, copy the `WhiteListIPs` element from the JSON returned by the above get call, edit it appropriately and use it in the following command:```oci db autonomous-database update –-autonomous-database-id --from-json ''```",
+ "AuditProcedure": "**From Console:**1. Login into the OCI Console2. Click in the search bar, top of the screen.3. Type Advanced Resource Query and hit enter.4. Click the `Advanced Resource Query` button in the upper right of the screen.5. Enter the following query in the query box:```query autonomousdatabase resources```6. For each ABD-S database returned click on the link under `Display name`7. Click `Edit` next to `Access Control List`8. Ensure `Access Control Rules’ IP Address/CIDR Block as well as VCNs are correct9. Repeat for other subscribed regions**From CLI:**1. Execute the following command:```for region in `oci iam region list | jq -r '.data[] | .name'`; do for compid in `oci iam compartment list --compartment-id-in-subtree TRUE 2>/dev/null | jq -r '.data[] | .id'` do for adbid in `oci db autonomous-database list --compartment-id $compid --region $region --all 2>/dev/null | jq -r '.data[] | select(.nsg-ids == null).id'` do output=`oci db autonomous-database get --autonomous-database-id $adbid --region $region --query=data.{WhiteListIPs:\\whitelisted-ips\\,id:id} --output table 2>/dev/null` if [ ! -z $output ]; then echo $output; fi done done done```2. Ensure `WhiteListIPs` are correct.",
+ "AdditionalInformation": "",
+ "References": "https://docs.oracle.com/en/cloud/paas/autonomous-database/adbsa/network-access-options.html#GUID-29D62917-0F18-4F3E-8081-B3BD5C0C79F5"
+ }
+ ]
+ },
+ {
+ "Id": "3.1",
+ "Description": "Ensure Compute Instance Legacy Metadata service endpoint is disabled",
+ "Checks": [
+ "compute_instance_legacy_metadata_endpoint_disabled"
+ ],
+ "Attributes": [
+ {
+ "Section": "3. Compute",
+ "Profile": "Level 2",
+ "AssessmentStatus": "Automated",
+ "Description": "Compute Instances that utilize Legacy MetaData service endpoints (IMDSv1) are susceptible to potential SSRF attacks. To bolster security measures, it is strongly advised to reconfigure Compute Instances to adopt Instance Metadata Service v2, aligning with the industry's best security practices.",
+ "RationaleStatement": "Enabling Instance Metadata Service v2 enhances security and grants precise control over metadata access. Transitioning from IMDSv1 reduces the risk of SSRF attacks, bolstering system protection.IMDv1 poses security risks due to its inferior security measures and limited auditing capabilities. Transitioning to IMDv2 ensures a more secure environment with robust security features and improved monitoring capabilities.",
+ "ImpactStatement": "If you disable IMDSv1 on an instance that does not support IMDSv2, you might not be able to connect to the instance when you launch it.IMDSv2 is supported on the following platform images:- Oracle Autonomous Linux 8.x images- Oracle Autonomous Linux 7.x images released in June 2020 or later- Oracle Linux 8.x, Oracle Linux 7.x, and Oracle Linux 6.x images released in July 2020 or laterOther platform images, most custom images, and most Marketplace images do not support IMDSv2. Custom Linux images might support IMDSv2 if cloud-init is updated to version 20.3 or later and Oracle Cloud Agent is updated to version 0.0.19 or later. Custom Windows images might support IMDSv2 if Oracle Cloud Agent is updated to version 1.0.0.0 or later; cloudbase-init does not support IMDSv2.",
+ "RemediationProcedure": "**From Console:**1. Login to the OCI Console2. Click on the search box at the top of the console and search for compute instance name.3. Click on the instance name, In the `Instance Details` section, next to Instance Metadata Service, click `Edit`.4. For the `Instance metadata service`, select the `Version 2 only` option.5. Click `Save Changes`.Note : Disabling IMDSv1 on an incompatible instance may result in connectivity issues upon launch.To re-enable IMDSv1, follow these steps: 1. On the Instance Details page in the Console, click `Edit` next to Instance Metadata Service.2. Choose the `Version 1 and version 2` option, and save your changes.**From CLI:**Run Below Command,```oci compute instance update --instance-id [instance-ocid] --instance-options '{areLegacyImdsEndpointsDisabled :true}'```This will set Instance Metadata Service to use Version 2 Only.",
+ "AuditProcedure": "**From Console:**1. Login to the OCI Console2. Select compute instance in your compartment.3. Click on each instance name.4. In the `Instance Details` section, next to `Instance metadata service` make sure `Version 2 only` is selected.**From CLI:**1. Run command:```for region in `oci iam region-subscription list | jq -r '.data[] | .region-name'`; do for compid in `oci iam compartment list --compartment-id-in-subtree TRUE 2>/dev/null | jq -r '.data[] | .id'` do output=`oci compute instance list --compartment-id $compid --region $region --all 2>/dev/null | jq -r '.data[] | select(.instance-options.are-legacy-imds-endpoints-disabled == false )'` if [ ! -z $output ]; then echo $output; fi done done```2. No results should be returned",
+ "AdditionalInformation": "",
+ "References": "https://docs.oracle.com/en-us/iaas/Content/Compute/Tasks/gettingmetadata.htm"
+ }
+ ]
+ },
+ {
+ "Id": "3.2",
+ "Description": "Ensure Secure Boot is enabled on Compute Instance",
+ "Checks": [
+ "compute_instance_secure_boot_enabled"
+ ],
+ "Attributes": [
+ {
+ "Section": "3. Compute",
+ "Profile": "Level 2",
+ "AssessmentStatus": "Automated",
+ "Description": "Shielded Instances with Secure Boot enabled prevents unauthorized boot loaders and operating systems from booting. This prevent rootkits, bootkits, and unauthorized software from running before the operating system loads.Secure Boot verifies the digital signature of the system's boot software to check its authenticity. The digital signature ensures the operating system has not been tampered with and is from a trusted source.When the system boots and attempts to execute the software, it will first check the digital signature to ensure validity. If the digital signature is not valid, the system will not allow the software to run.Secure Boot is a feature of UEFI(Unified Extensible Firmware Interface) that only allows approved operating systems to boot up.",
+ "RationaleStatement": "A Threat Actor with access to the operating system may seek to alter boot components to persist malware or rootkits during system initialization. Secure Boot helps ensure that the system only runs authentic software by verifying the digital signature of all boot components.",
+ "ImpactStatement": "An existing instance cannot be changed to a Shielded instance with Secure boot enabled. Shielded Secure Boot not available on all instance shapes and Operating systems. Additionally the following limitations exist:Thus to enable you have to terminate the instance and create a new one. Also, Shielded instances do not support live migration. During an infrastructure maintenance event, Oracle Cloud Infrastructure live migrates supported VM instances from the physical VM host that needs maintenance to a healthy VM host with minimal disruption to running instances. If you enable Secure Boot on an instance, the instance cannot be migrated, because the hardware TPM is not migratable. This may result in an outage because the TPM can't be migrate from a unhealthy host to healthy host.",
+ "RemediationProcedure": "Note: Secure Boot facility is available on selected VM images and Shapes in OCI. User have to configure Secured Boot at time of instance creation only.**From Console:**1. Navigate to https://cloud.oracle.com/compute/instances1. Select the instance from the Audit Procedure1. Click `Terminate`.1. Determine whether or not to permanently delete instance's attached boot volume.1. Click `Terminate instance`.1. Click on `Create Instance`.1. Select Image and Shape which supports Shielded Instance configuration. Icon for Shield in front of Image/Shape row indicates support of Shielded Instance.1. Click on `edit` of Security Blade.1. Turn On Shielded Instance, then Turn on the Secure Boot Toggle.1. Fill in the rest of the details as per requirements.1. Click `Create`.",
+ "AuditProcedure": "**From Console:**1. Login to the OCI Console2. Select compute instance in your compartment.3. Click on each instance name.4. In the `Launch Options` section,5. Check if `Secure Boot` is `Enabled`.**From CLI:**Run command:```for region in `oci iam region-subscription list | jq -r '.data[] | .region-name'`; do for compid in `oci iam compartment list --compartment-id-in-subtree TRUE 2>/dev/null | jq -r '.data[] | .id'` do output=`oci compute instance list --compartment-id $compid --region $region --all 2>/dev/null | jq -r '.data[] | select(.platform-config == null or platform-config.is-secure-boot-enabled == false )'` if [ ! -z $output ]; then echo $output; fi done done```In response, check if `platform-config` are not null and `is-secure-boot-enabled` is set to `true`",
+ "AdditionalInformation": "",
+ "References": "https://docs.oracle.com/en-us/iaas/Content/Compute/References/shielded-instances.htm:https://uefi.org/sites/default/files/resources/UEFI_Secure_Boot_in_Modern_Computer_Security_Solutions_2013.pdf"
+ }
+ ]
+ },
+ {
+ "Id": "3.3",
+ "Description": "Ensure In-transit Encryption is enabled on Compute Instance",
+ "Checks": [
+ "compute_instance_in_transit_encryption_enabled"
+ ],
+ "Attributes": [
+ {
+ "Section": "3. Compute",
+ "Profile": "Level 1",
+ "AssessmentStatus": "Automated",
+ "Description": "The Block Volume service provides the option to enable in-transit encryption for paravirtualized volume attachments on virtual machine (VM) instances.",
+ "RationaleStatement": "All the data moving between the instance and the block volume is transferred over an internal and highly secure network. If you have specific compliance requirements related to the encryption of the data while it is moving between the instance and the block volume, you should enable the in-transit encryption option.",
+ "ImpactStatement": "In-transit encryption for boot and block volumes is only available for virtual machine (VM) instances launched from platform images, along with bare metal instances that use the following shapes: BM.Standard.E3.128, BM.Standard.E4.128, BM.DenseIO.E4.128. It is not supported on other bare metal instances.",
+ "RemediationProcedure": "**From Console:**1. Navigate to https://cloud.oracle.com/compute/instances1. Select the instance from the Audit Procedure1. Click `Terminate`.1. Determine whether or not to permanently delete instance's attached boot volume.1. Click `Terminate instance`.1. Click on `Create Instance`.1. Fill in the details as per requirements.1. In the `Boot volume` section ensure `Use in-transit encryption` is checked.1. Fill in the rest of the details as per requirements.1. Click `Create`.",
+ "AuditProcedure": "**From Console:**1. Go to [https://cloud.oracle.com/compute/instances](https://cloud.oracle.com/compute/instances)2. Select compute instance in your compartment.3. Click on each instance name.4. Click on `Boot volume` on the bottom left.5. Under the `In-transit encryption` column make sure it is `Enabled`**From CLI:**1. Execute the following:```for region in `oci iam region-subscription list | jq -r '.data[] | .region-name'`; do for compid in `oci iam compartment list --compartment-id-in-subtree TRUE 2>/dev/null | jq -r '.data[] | .id'` do output=`oci compute instance list --compartment-id $compid --region $region --all 2>/dev/null | jq -r '.data[] | select(.launch-options.is-pv-encryption-in-transit-enabled == false )'` if [ ! -z $output ]; then echo $output; fi done done```2. Ensure no results are returned",
+ "AdditionalInformation": "",
+ "References": "https://docs.oracle.com/en-us/iaas/Content/Block/Concepts/overview.htm#BlockVolumeEncryption__intransit"
+ }
+ ]
+ },
+ {
+ "Id": "4.1",
+ "Description": "Ensure default tags are used on resources",
+ "Checks": [],
+ "Attributes": [
+ {
+ "Section": "4. Logging and Monitoring",
+ "Profile": "Level 1",
+ "AssessmentStatus": "Automated",
+ "Description": "Using default tags is a way to ensure all resources that support tags are tagged during creation. Tags can be based on static or computed values. It is recommended to set up default tags early after root compartment creation to ensure all created resources will get tagged.Tags are scoped to Compartments and are inherited by Child Compartments. The recommendation is to create default tags like “CreatedBy” at the Root Compartment level to ensure all resources get tagged.When using Tags it is important to ensure that Tag Namespaces are protected by IAM Policies otherwise this will allow users to change tags or tag values.Depending on the age of the OCI Tenancy there may already be Tag defaults setup at the Root Level and no need for further action to implement this action.",
+ "RationaleStatement": "In the case of an incident having default tags like “CreatedBy” applied will provide info on who created the resource without having to search the Audit logs.",
+ "ImpactStatement": "There is no performance impact when enabling the above described features.",
+ "RemediationProcedure": "**From Console:**1. Login to OCI Console.2. From the navigation menu, select `Governance & Administration`.3. Under `Tenancy Management`, select `Tag Namespaces`.4. Under `Compartment`, select the root compartment.5. If no tag namespace exists, click `Create Tag Namespace`, enter a name and description and click `Create Tag Namespace`.6. Click the name of a tag namespace.7. Click `Create Tag Key Definition`.8. Enter a tag key (e.g. CreatedBy) and description, and click `Create Tag Key Definition`.9. From the navigation menu, select `Identity & Security`.10. Under `Identity`, select `Compartments`.11. Click the name of the root compartment.12. Under `Resources`, select `Tag Defaults`.13. Click `Create Tag Default`.14. Select a tag namespace, tag key, and enter `${iam.principal.name}` as the tag value.15. Click `Create`.**From CLI:**1. Create a Tag Namespace in the Root Compartment```oci iam tag-namespace create --compartment-id= --name= --description= --query data.{\\Tag Namespace OCID\\:id} --output table```2. Note the Tag Namespace OCID and use it when creating the Tag Key Definition```oci iam tag create --tag-namespace-id= --name= --description= --query data.{\\Tag Key Definition OCID\\:id} --output table```3. Note the Tag Key Definition OCID and use it when creating the Tag Default in the Root compartment```oci iam tag-default create --compartment-id= --tag-definition-id= --value=\\${iam.principal.name}```",
+ "AuditProcedure": "**From Console:**1. Login to OCI Console.2. From the navigation menu, select `Identity & Security`.3. Under `Identity`, select `Compartments`.4. Click the name of the root compartment.5. Under `Resources`, select `Tag Defaults`.6. In the `Tag Defaults` table, verify that there is a Tag with a value of `${iam.principal.name}` and a Tag Key Status of `Active`.Note: The name of the tag may be different then “CreatedBy” if the Tenancy Administrator has decided to use another tag.**From CLI:**1. List the active tag defaults defined at the Root compartment level by using the Tenancy OCID as compartment id.Note: The Tenancy OCID can be found in the `~/.oci/config` file used by the OCI Command Line Tool```oci iam tag-default list --compartment-id= --query=data [?\\lifecycle-state\\=='ACTIVE'].{name:\\tag-definition-name\\,value:value} --output table```2. Verify in the table returned that there is at least one row that contains the value of `${iam.principal.name}`.",
+ "AdditionalInformation": "'- There is no requirement to use the “Oracle-Tags” namespace to implement this control. A Tag Namespace Administrator can create any namespace and use it for this control.",
+ "References": ""
+ }
+ ]
+ },
+ {
+ "Id": "4.2",
+ "Description": "Create at least one notification topic and subscription to receive monitoring alerts",
+ "Checks": [
+ "events_notification_topic_and_subscription_exists"
+ ],
+ "Attributes": [
+ {
+ "Section": "4. Logging and Monitoring",
+ "Profile": "Level 1",
+ "AssessmentStatus": "Automated",
+ "Description": "Notifications provide a multi-channel messaging service that allow users and applications to be notified of events of interest occurring within OCI. Messages can be sent via eMail, HTTPs, PagerDuty, Slack or the OCI Function service. Some channels, such as eMail require confirmation of the subscription before it becomes active.",
+ "RationaleStatement": "Creating one or more notification topics allow administrators to be notified of relevant changes made to OCI infrastructure.",
+ "ImpactStatement": "There is no performance impact when enabling the above described features but depending on the amount of notifications sent per month there may be a cost associated.",
+ "RemediationProcedure": "**From Console:**1. Go to the Notifications Service page: [https://console.us-ashburn-1.oraclecloud.com/notification/topics](https://console.us-ashburn-1.oraclecloud.com/notification/topics)2. Select the `Compartment` that hosts the notifications3. Click `Create Topic`4. Set the `name` to something relevant5. Set the `description` to describe the purpose of the topic6. Click `Create`7. Click the newly created topic8. Click `Create Subscription`9. Choose the correct `protocol`10. Complete the correct parameter, for instance `email` address11. Click `Create`**From CLI:**1. Create a topic in a compartment```oci ons topic create --name --description --compartment-id ```2. Note the `OCID` of the `topic` using the `topic-id` field of the returned JSON and use it to create a new subscription```oci ons subscription create --compartment-id --topic-id --protocol --subscription-endpoint ```3. The returned JSON includes the id of the `subscription`.",
+ "AuditProcedure": "**From Console:**1. Go to the Notifications Service page: [https://console.us-ashburn-1.oraclecloud.com/notification/topics](https://console.us-ashburn-1.oraclecloud.com/notification/topics)2. Select the `Compartment` that hosts the notifications3. Find and click the `Topic` relevant to your monitoring alerts.4. Ensure a valid active subscription is shown.**From CLI:** 1. List the topics in the `Compartment` that hosts the notifications```oci ons topic list --compartment-id --all```2. Note the `OCID` of the monitoring topic(s) using the `topic-id` field of the returned JSON and use it to list the subscriptions```oci ons subscription list --compartment-id --topic-id --all```3. Ensure at least one active subscription is returned",
+ "AdditionalInformation": "'- The console URL shown is for the Ashburn region. Your tenancy might have a different home region and thus console URL.- The same Notification topic can be reused by many Events. A single topic can have multiple subscriptions allowing the same topic to be published to multiple locations.- The generated notification will include an eventID that can be used when querying the Audit Logs in case further investigation is required.",
+ "References": ""
+ }
+ ]
+ },
+ {
+ "Id": "4.3",
+ "Description": "Ensure a notification is configured for Identity Provider changes",
+ "Checks": [
+ "events_rule_identity_provider_changes"
+ ],
+ "Attributes": [
+ {
+ "Section": "4. Logging and Monitoring",
+ "Profile": "Level 1",
+ "AssessmentStatus": "Automated",
+ "Description": "It is recommended to setup an Event Rule and Notification that gets triggered when Identity Providers are created, updated or deleted. Event Rules are compartment scoped and will detect events in child compartments. It is recommended to create the Event rule at the root compartment level.",
+ "RationaleStatement": "OCI Identity Providers allow management of User ID / passwords in external systems and use of those credentials to access OCI resources. Identity Providers allow users to single sign-on to OCI console and have other OCI credentials like API Keys.Monitoring and alerting on changes to Identity Providers will help in identifying changes to the security posture.",
+ "ImpactStatement": "There is no performance impact when enabling the above described features but depending on the amount of notifications sent per month there may be a cost associated.",
+ "RemediationProcedure": "**From Console:**1. Go to the `Events Service` page: [https://cloud.oracle.com/events/rules](https://cloud.oracle.com/events/rules)2. Select the `compartment` that should host the rule3. Click `Create Rule`4. Provide a `Display Name` and `Description`5. Create a Rule Condition by selecting `Identity` in the Service Name Drop-down and selecting `Identity Provider – Create`, `Identity Provider - Delete and Identity Provider – Update`6. In the `Actions` section select `Notifications` as Action Type7. Select the `Compartment` that hosts the Topic to be used.8. Select the `Topic` to be used9. Optionally add Tags to the Rule10. Click `Create Rule`**From CLI:**1. Find the `topic-id` of the topic the Event Rule should use for sending notifications by using the topic `name` and `Compartment OCID````oci ons topic list --compartment-id --all --query data [?name==''].{name:name,topic_id:\\topic-id\\} --output table```2. Create a JSON file to be used when creating the Event Rule. Replace topic id, display name, description and compartment OCID.```{ actions: { actions: [ { actionType: ONS, isEnabled: true, topicId: }] }, condition:{\\eventType\\:[\\com.oraclecloud.identitycontrolplane.createidentityprovider\\,\\ com.oraclecloud.identitycontrolplane.deleteidentityprovider\\,\\ com.oraclecloud.identitycontrolplane.updateidentityprovider\\],\\data\\:{}}, displayName: , description: , isEnabled: true, compartmentId: }```3. Create the actual event rule```oci events rule create --from-json file://event_rule.json```4. Note in the JSON returned that it lists the parameters specified in the JSON file provided and that there is an OCID provided for the Event Rule",
+ "AuditProcedure": "**From Console:**1. Go to the Events Service page: [https://cloud.oracle.com/events/rules](https://cloud.oracle.com/events/rules)2. Select the `Compartment` that hosts the rules3. Find and click the `Rule` that handles `Identity Provider` Changes (if any)4. Click the `Edit Rule` button and verify that the `RuleConditions` section contains a condition for the Service `Identity` and Event Types: `Identity Provider – Create`, `Identity Provider - Delete` and `Identity Provider – Update`5. Verify that in the `Actions` section the Action Type contains: `Notifications` and that a valid `Topic` is referenced.**From CLI:** 1. Find the OCID of the specific Event Rule based on Display Name and Compartment OCID```oci events rule list --compartment-id --query data [?\\display-name\\==''].{id:id} --output table```2. List the details of a specific Event Rule based on the OCID of the rule.```oci events rule get --rule-id ```3. In the JSON output locate the Conditions key value pair and verify that the following Conditions are present:```com.oraclecloud.identitycontrolplane.createidentityprovidercom.oraclecloud.identitycontrolplane.deleteidentityprovidercom.oraclecloud.identitycontrolplane.updateidentityprovider```4. Verify the value of the `is-enabled` attribute is `true`5. In the JSON output verify that `actionType` is `ONS` and locate the `topic-id`6. Verify the correct topic is used by checking the topic name```oci ons topic get --topic-id --query data.{name:name} --output table```",
+ "AdditionalInformation": "'- The same Notification topic can be reused by many Event Rules.- The generated notification will include an eventID that can be used when querying the Audit Logs in case further investigation is required.",
+ "References": ""
+ }
+ ]
+ },
+ {
+ "Id": "4.4",
+ "Description": "Ensure a notification is configured for IdP group mapping changes",
+ "Checks": [
+ "events_rule_idp_group_mapping_changes"
+ ],
+ "Attributes": [
+ {
+ "Section": "4. Logging and Monitoring",
+ "Profile": "Level 1",
+ "AssessmentStatus": "Automated",
+ "Description": "It is recommended to setup an Event Rule and Notification that gets triggered when Identity Provider Group Mappings are created, updated or deleted. Event Rules are compartment scoped and will detect events in child compartments. It is recommended to create the Event rule at the root compartment level.",
+ "RationaleStatement": "IAM Policies govern access to all resources within an OCI Tenancy. IAM Policies use OCI Groups for assigning the privileges. Identity Provider Groups could be mapped to OCI Groups to assign privileges to federated users in OCI. Monitoring and alerting on changes to Identity Provider Group mappings will help in identifying changes to the security posture.",
+ "ImpactStatement": "There is no performance impact when enabling the above described features but depending on the amount of notifications sent per month there may be a cost associated.",
+ "RemediationProcedure": "**From Console:**1. Go to the `Events Service` page: [https://cloud.oracle.com/events/rules](https://cloud.oracle.com/events/rules)2. Select the `compartment` that should host the rule3. Click `Create Rule`4. Provide a `Display Name` and `Description`5. Create a Rule Condition by selecting `Identity` in the Service Name Drop-down and selecting `Idp Group Mapping – Create`, `Idp Group Mapping – Delete` and `Idp Group Mapping – Update`6. In the `Actions` section select `Notifications` as Action Type7. Select the `Compartment` that hosts the Topic to be used.8. Select the `Topic` to be used9. Optionally add Tags to the Rule10. Click `Create Rule`**From CLI:**1. Find the `topic-id` of the topic the Event Rule should use for sending notifications by using the topic `name` and `Compartment OCID````oci ons topic list --compartment-id --all --query data [?name==''].{name:name,topic_id:\\topic-id\\} --output table```2. Create a JSON file to be used when creating the Event Rule. Replace topic id, display name, description and compartment OCID.```{ actions: { actions: [ { actionType: ONS, isEnabled: true, topicId: }] }, condition:{\\eventType\\:[\\com.oraclecloud.identitycontrolplane.addidpgroupmapping\\,\\com.oraclecloud.identitycontrolplane.removeidpgroupmapping\\,\\com.oraclecloud.identitycontrolplane.updateidpgroupmapping\\],\\data\\:{}}, displayName: , description: , isEnabled: true, compartmentId: }```3. Create the actual event rule```oci events rule create --from-json file://event_rule.json```4. Note in the JSON returned that it lists the parameters specified in the JSON file provided and that there is an OCID provided for the Event Rule",
+ "AuditProcedure": "**From Console:**1. Go to the Events Service page: [https://cloud.oracle.com/events/rules](https://cloud.oracle.com/events/rules)2. Select the `Compartment` that hosts the rules3. Find and click the `Rule` that handles `Idp Group Mapping` Changes (if any)4. Ensure the `Rule` is `ACTIVE`5. Click the `Edit Rule` button and verify that the `RuleConditions` section contains a condition for the Service `Identity` and Event Types: `Idp Group Mapping – Create`, `Idp Group Mapping – Delete` and `Idp Group Mapping – Update`6. Verify that in the `Actions` section the Action Type contains: `Notifications` and that a valid `Topic` is referenced.**From CLI:** 1. Find the OCID of the specific Event Rule based on Display Name and Compartment OCID```oci events rule list --compartment-id --query data [?\\display-name\\==''].{id:id} --output table```2. List the details of a specific Event Rule based on the OCID of the rule.```oci events rule get --rule-id ```3. In the JSON output locate the Conditions key value pair and verify that the following Conditions are present:```com.oraclecloud.identitycontrolplane.addidpgroupmappingcom.oraclecloud.identitycontrolplane.removeidpgroupmappingcom.oraclecloud.identitycontrolplane.updateidpgroupmapping```4. Verify the value of the `is-enabled` attribute is `true`5. In the JSON output verify that `actionType` is `ONS` and locate the `topic-id`6. Verify the correct topic is used by checking the topic name```oci ons topic get --topic-id --query data.{name:name} --output table```",
+ "AdditionalInformation": "'- The same Notification topic can be reused by many Event Rules.- The generated notification will include an eventID that can be used when querying the Audit Logs in case further investigation is required.",
+ "References": ""
+ }
+ ]
+ },
+ {
+ "Id": "4.5",
+ "Description": "Ensure a notification is configured for IAM group changes",
+ "Checks": [
+ "events_rule_iam_group_changes"
+ ],
+ "Attributes": [
+ {
+ "Section": "4. Logging and Monitoring",
+ "Profile": "Level 1",
+ "AssessmentStatus": "Automated",
+ "Description": "It is recommended to setup an Event Rule and Notification that gets triggered when IAM Groups are created, updated or deleted. Event Rules are compartment scoped and will detect events in child compartments, it is recommended to create the Event rule at the root compartment level.",
+ "RationaleStatement": "IAM Groups control access to all resources within an OCI Tenancy. Monitoring and alerting on changes to IAM Groups will help in identifying changes to satisfy least privilege principle.",
+ "ImpactStatement": "There is no performance impact when enabling the above described features but depending on the amount of notifications sent per month there may be a cost associated.",
+ "RemediationProcedure": "**From Console:**1. Go to the `Events Service` page: [https://cloud.oracle.com/events/rules](https://cloud.oracle.com/events/rules)2. Select the `compartment` that should host the rule3. Click `Create Rule`4. Provide a `Display Name` and `Description`5. Create a Rule Condition by selecting `Identity` in the Service Name Drop-down and selecting `Group – Create`, `Group – Delete` and `Group – Update`6. In the `Actions` section select `Notifications` as Action Type7. Select the `Compartment` that hosts the Topic to be used.8. Select the `Topic` to be used9. Optionally add Tags to the Rule10. Click `Create Rule`**From CLI:**1. Find the `topic-id` of the topic the Event Rule should use for sending Notifications by using the topic `name` and `Compartment OCID````oci ons topic list --compartment-id --all --query data [?name==''].{name:name,topic_id:\\topic-id\\} --output table```2. Create a JSON file to be used when creating the Event Rule. Replace topic id, display name, description and compartment OCID.```{ actions: { actions: [ { actionType: ONS, isEnabled: true, topicId: }] }, condition: {\\eventType\\:[\\com.oraclecloud.identitycontrolplane.creategroup\\,\\com.oraclecloud.identitycontrolplane.deletegroup\\,\\com.oraclecloud.identitycontrolplane.updategroup\\],\\data\\:{}}, displayName: , description: , isEnabled: true, compartmentId: }```3. Create the actual event rule```oci events rule create --from-json file://event_rule.json```4. Note in the JSON returned that it lists the parameters specified in the JSON file provided and that there is an OCID provided for the Event Rule",
+ "AuditProcedure": "**From Console:**1. Go to the `Events Service` page: [https://cloud.oracle.com/events/rules](https://cloud.oracle.com/events/rules)2. Select the `Compartment` that hosts the rules3. Find and click the `Rule` that handles IAM `Group` Changes4. Click the `Edit Rule` button and verify that the `Rule Conditions` section contains a condition for the Service `Identity` and Event Types: `Group – Create`, `Group – Delete` and `Group – Update`5. Verify that in the `Actions` section the Action Type contains: `Notifications` and that a valid `Topic` is referenced.**From CLI:**1. Find the OCID of the specific Event Rule based on `Display Name` and `Compartment OCID````oci events rule list --compartment-id --query data [?\\display-name\\==''].{id:id} --output table```2. List the details of a specific Event Rule based on the OCID of the rule.```oci events rule get --rule-id ```3. In the JSON output locate the Conditions key value pair and verify that the following Conditions are present:```com.oraclecloud.identitycontrolplane.creategroupcom.oraclecloud.identitycontrolplane.deletegroupcom.oraclecloud.identitycontrolplane.updategroup```4. Verify the value of the `is-enabled` attribute is `true`5. In the JSON output verify that `actionType` is ONS and locate the `topic-id`6. Verify the correct topic is used by checking the topic name```oci ons topic get --topic-id --query data.{name:name} --output table```",
+ "AdditionalInformation": "'- The same Notification topic can be reused by many Event Rules.- The generated notification will include an eventID that can be used when querying the Audit Logs in case further investigation is required.",
+ "References": ""
+ }
+ ]
+ },
+ {
+ "Id": "4.6",
+ "Description": "Ensure a notification is configured for IAM policy changes",
+ "Checks": [
+ "events_rule_iam_policy_changes"
+ ],
+ "Attributes": [
+ {
+ "Section": "4. Logging and Monitoring",
+ "Profile": "Level 1",
+ "AssessmentStatus": "Automated",
+ "Description": "It is recommended to setup an Event Rule and Notification that gets triggered when IAM Policies are created, updated or deleted. Event Rules are compartment scoped and will detect events in child compartments, it is recommended to create the Event rule at the root compartment level.",
+ "RationaleStatement": "IAM Policies govern access to all resources within an OCI Tenancy. Monitoring and alerting on changes to IAM policies will help in identifying changes to the security posture.",
+ "ImpactStatement": "There is no performance impact when enabling the above described features but depending on the amount of notifications sent per month there may be a cost associated.",
+ "RemediationProcedure": "**From Console:**1. Go to the `Events Service` page: [https://cloud.oracle.com/events/rules](https://cloud.oracle.com/events/rules)2. Select the `compartment` that should host the rule3. Click `Create Rule`4. Provide a `Display Name` and `Description`5. Create a Rule Condition by selecting `Identity` in the Service Name Drop-down and selecting `Policy – Change Compartment`, `Policy – Create`, `Policy - Delete` and `Policy – Update`6. In the `Actions` section select `Notifications` as Action Type7. Select the `Compartment` that hosts the Topic to be used.8. Select the `Topic` to be used9. Optionally add Tags to the Rule10. Click `Create Rule`**From CLI:**1. Find the `topic-id` of the topic the Event Rule should use for sending Notifications by using the topic `name` and `Compartment OCID````oci ons topic list --compartment-id --all --query data [?name==''].{name:name,topic_id:\\topic-id\\} --output table```2. Create a JSON file to be used when creating the Event Rule. Replace topic id, display name, description and compartment OCID.```{ actions: { actions: [ { actionType: ONS, isEnabled: true, topicId: }] }, condition:{\\eventType\\:[\\com.oraclecloud.identitycontrolplane.createpolicy\\,\\com.oraclecloud.identitycontrolplane.deletepolicy\\,\\com.oraclecloud.identitycontrolplane.updatepolicy\\],\\data\\:{}}, displayName: , description: , isEnabled: true, compartmentId: }```3. Create the actual event rule```oci events rule create --from-json file://event_rule.json```4. Note in the JSON returned that it lists the parameters specified in the JSON file provided and that there is an OCID provided for the Event Rule",
+ "AuditProcedure": "**From Console:**1. Go to the Events Service page: [https://cloud.oracle.com/events/rules](https://cloud.oracle.com/events/rules)2. Select the `Compartment` that hosts the rules3. Find and click the `Rule` that handles `IAM Policy` Changes (if any)4. Click the `Edit Rule` button and verify that the `RuleConditions` section contains a condition for the Service `Identity` and Event Types: `Policy – Create`, ` Policy - Delete` and `Policy – Update`5. Verify that in the `Actions` section the Action Type contains: `Notifications` and that a valid `Topic` is referenced.**From CLI:** 1. Find the OCID of the specific Event Rule based on Display Name and Compartment OCID```oci events rule list --compartment-id --query data [?\\display-name\\==''].{id:id} --output table```2. List the details of a specific Event Rule based on the OCID of the rule.```oci events rule get --rule-id ```3. In the JSON output locate the Conditions key value pair and verify that the following Conditions are present:```com.oraclecloud.identitycontrolplane.createpolicycom.oraclecloud.identitycontrolplane.deletepolicycom.oraclecloud.identitycontrolplane.updatepolicy```4. Verify the value of the `is-enabled` attribute is `true`5. In the JSON output verify that `actionType` is `ONS` and locate the `topic-id`6. Verify the correct topic is used by checking the topic name```oci ons topic get --topic-id --query data.{name:name} --output table```",
+ "AdditionalInformation": "'- The same Notification topic can be reused by many Event Rules.- The generated notification will include an eventID that can be used when querying the Audit Logs in case further investigation is required.",
+ "References": ""
+ }
+ ]
+ },
+ {
+ "Id": "4.7",
+ "Description": "Ensure a notification is configured for user changes",
+ "Checks": [
+ "events_rule_user_changes"
+ ],
+ "Attributes": [
+ {
+ "Section": "4. Logging and Monitoring",
+ "Profile": "Level 1",
+ "AssessmentStatus": "Automated",
+ "Description": "It is recommended to setup an Event Rule and Notification that gets triggered when IAM Users are created, updated, deleted, capabilities updated, or state updated. Event Rules are compartment scoped and will detect events in child compartments, it is recommended to create the Event rule at the root compartment level.",
+ "RationaleStatement": "Users use or manage Oracle Cloud Infrastructure resources. Monitoring and alerting on changes to Users will help in identifying changes to the security posture.",
+ "ImpactStatement": "There is no performance impact when enabling the above described features but depending on the amount of notifications sent per month there may be a cost associated.",
+ "RemediationProcedure": "**From Console:**1. Using the search box to navigate to `events`2. Navigate to the `rules` page3. Select the `compartment` that should host the rule4. Click `Create Rule`5. Provide a `Display Name` and `Description`6. Create a Rule Condition by selecting `Identity` in the Service Name Drop-down and selecting:`User – Create`, `User – Delete`, `User – Update`, `User Capabilities – Update`,`User State – Update` 7. In the `Actions` section select `Notifications` as Action Type8. Select the `Compartment` that hosts the Topic to be used.9. Select the `Topic` to be used10. Optionally add Tags to the Rule11. Click `Create Rule`**From CLI:**1. Find the `topic-id` of the topic the Event Rule should use for sending Notifications by using the topic `name` and `Compartment OCID````oci ons topic list --compartment-id --all --query data [?name==''].{name:name,topic_id:\\topic-id\\} --output table```2. Create a JSON file to be used when creating the Event Rule. Replace topic id, display name, description and compartment OCID.```{ actions: { actions: [ { actionType: ONS, isEnabled: true, topicId: }] }, condition: {\\eventType\\:[\\com.oraclecloud.identitycontrolplane.createuser\\,\\com.oraclecloud.identitycontrolplane.deleteuser\\,\\com.oraclecloud.identitycontrolplane.updateuser\\,\\com.oraclecloud.identitycontrolplane.updateusercapabilities\\,\\com.oraclecloud.identitycontrolplane.updateuserstate\\],\\data\\:{}}, displayName: , description: , isEnabled: true, compartmentId: }```3. Create the actual event rule```oci events rule create --from-json file://event_rule.json```4. Note in the JSON returned that it lists the parameters specified in the JSON file provided and that there is an OCID provided for the Event Rule",
+ "AuditProcedure": "**From Console:**1. Using the search box to navigate to `events`2. Navigate to the `rules` page3. Select the `Compartment` that hosts the rules4. Find and click the `Rule` that handles `IAM User` Changes5. Click the `Edit Rule` button and verify that the `Rule Conditions` section contains a condition for the Service `Identity` and Event Types: `User – Create`, `User – Delete`, `User – Update`, `User Capabilities – Update`,`User State – Update` 6. Verify that in the `Actions` section the Action Type contains: `Notifications` and that a valid `Topic` is referenced.**From CLI:**1. Find the OCID of the specific Event Rule based on `Display Name` and `Compartment OCID````oci events rule list --compartment-id --query data [?\\display-name\\==''].{id:id} --output table```2. List the details of a specific Event Rule based on the OCID of the rule.```oci events rule get --rule-id ```3. In the JSON output locate the Conditions key value pair and verify that the following Conditions are present:```com.oraclecloud.identitycontrolplane.createusercom.oraclecloud.identitycontrolplane.deleteusercom.oraclecloud.identitycontrolplane.updateusercom.oraclecloud.identitycontrolplane.updateusercapabilitiescom.oraclecloud.identitycontrolplane.updateuserstate```4. Verify the value of the `is-enabled` attribute is `true`5. In the JSON output verify that `actionType` is ONS and locate the `topic-id`6. Verify the correct topic is used by checking the topic name```oci ons topic get --topic-id --query data.{name:name} --output table```",
+ "AdditionalInformation": "'- The same Notification topic can be reused by many Event Rules.- The generated notification will include an eventID that can be used when querying the Audit Logs in case further investigation is required.",
+ "References": ""
+ }
+ ]
+ },
+ {
+ "Id": "4.8",
+ "Description": "Ensure a notification is configured for VCN changes",
+ "Checks": [
+ "events_rule_vcn_changes"
+ ],
+ "Attributes": [
+ {
+ "Section": "4. Logging and Monitoring",
+ "Profile": "Level 1",
+ "AssessmentStatus": "Automated",
+ "Description": "It is recommended to setup an Event Rule and Notification that gets triggered when Virtual Cloud Networks are created, updated or deleted. Event Rules are compartment scoped and will detect events in child compartments, it is recommended to create the Event rule at the root compartment level.",
+ "RationaleStatement": "Virtual Cloud Networks (VCNs) closely resembles a traditional network. Monitoring and alerting on changes to VCNs will help in identifying changes to the security posture.",
+ "ImpactStatement": "There is no performance impact when enabling the above described features but depending on the amount of notifications sent per month there may be a cost associated.",
+ "RemediationProcedure": "**From Console:**1. Go to the `Events Service` page: [https://cloud.oracle.com/events/rules](https://cloud.oracle.com/events/rules)2. Select the `compartment` that should host the rule3. Click `Create Rule`4. Provide a `Display Name` and `Description`5. Create a Rule Condition by selecting `Networking` in the Service Name Drop-down and selecting `VCN – Create`, ` VCN - Delete and VCN – Update`6. In the `Actions` section select `Notifications` as Action Type7. Select the `Compartment` that hosts the Topic to be used.8. Select the `Topic` to be used9. Optionally add Tags to the Rule10. Click `Create Rule`**From CLI:**1. Find the `topic-id` of the topic the Event Rule should use for sending Notifications by using the topic `name` and `Compartment OCID````oci ons topic list --compartment-id --all --query data [?name==''].{name:name,topic_id:\\topic-id\\} --output table```2. Create a JSON file to be used when creating the Event Rule. Replace topic id, display name, description and compartment OCID.```{ actions: { actions: [ { actionType: ONS, isEnabled: true, topicId: }] }, condition:{\\eventType\\:[\\com.oraclecloud.virtualnetwork.createvcn\\,\\com.oraclecloud.virtualnetwork.deletevcn\\,\\com.oraclecloud.virtualnetwork.updatevcn\\],\\data\\:{}}, displayName: , description: , isEnabled: true, compartmentId: }```3. Create the actual event rule```oci events rule create --from-json file://event_rule.json```4. Note in the JSON returned that it lists the parameters specified in the JSON file provided and that there is an OCID provided for the Event Rule",
+ "AuditProcedure": "**From Console:**1. Go to the Events Service page: [https://cloud.oracle.com/events/rules](https://cloud.oracle.com/events/rules)2. Select the `Compartment` that hosts the rules3. Find and click the `Rule` that handles `VCN` Changes (if any)4. Click the `Edit Rule` button and verify that the `RuleConditions` section contains a condition for the Service `Networking` and Event Types: `VCN – Create`, ` VCN - Delete and VCN – Update`5. Verify that in the `Actions` section the Action Type contains: `Notifications` and that a valid `Topic` is referenced.**From CLI:**1. Find the OCID of the specific Event Rule based on Display Name and Compartment OCID```oci events rule list --compartment-id --query data [?\\display-name\\==''].{id:id} --output table```2. List the details of a specific Event Rule based on the OCID of the rule.```oci events rule get --rule-id ```3. In the JSON output locate the Conditions key value pair and verify that the following Conditions are present:```com.oraclecloud.virtualnetwork.createvcncom.oraclecloud.virtualnetwork.deletevcncom.oraclecloud.virtualnetwork.updatevcn```4. Verify the value of the `is-enabled` attribute is `true`5. In the JSON output verify that `actionType` is `ONS` and locate the `topic-id`6. Verify the correct topic is used by checking the topic name```oci ons topic get --topic-id --query data.{name:name} --output table```",
+ "AdditionalInformation": "'- The same Notification topic can be reused by many Event Rules.- The generated notification will include an eventID that can be used when querying the Audit Logs in case further investigation is required.",
+ "References": ""
+ }
+ ]
+ },
+ {
+ "Id": "4.9",
+ "Description": "Ensure a notification is configured for changes to route tables",
+ "Checks": [
+ "events_rule_route_table_changes"
+ ],
+ "Attributes": [
+ {
+ "Section": "4. Logging and Monitoring",
+ "Profile": "Level 1",
+ "AssessmentStatus": "Automated",
+ "Description": "It is recommended to setup an Event Rule and Notification that gets triggered when route tables are created, updated or deleted. Event Rules are compartment scoped and will detect events in child compartments, it is recommended to create the Event rule at the root compartment level.",
+ "RationaleStatement": "Route tables control traffic flowing to or from Virtual Cloud Networks and Subnets. Monitoring and alerting on changes to route tables will help in identifying changes these traffic flows.",
+ "ImpactStatement": "There is no performance impact when enabling the above described features but depending on the amount of notifications sent per month there may be a cost associated.",
+ "RemediationProcedure": "**From Console:**1. Go to the `Events Service` page: [https://cloud.oracle.com/events/rules](https://cloud.oracle.com/events/rules)2. Select the `compartment` that should host the rule3. Click `Create Rule`4. Provide a `Display Name` and `Description`5. Create a Rule Condition by selecting `Networking` in the Service Name Drop-down and selecting `Route Table – Change Compartment`, `Route Table – Create`, `Route Table - Delete` and `Route Table – Update`6. In the `Actions` section select `Notifications` as Action Type7. Select the `Compartment` that hosts the Topic to be used.8. Select the `Topic` to be used9. Optionally add Tags to the Rule10. Click `Create Rule`**From CLI:**1. Find the `topic-id` of the topic the Event Rule should use for sending Notifications by using the topic `name` and `Compartment OCID````oci ons topic list --compartment-id --all --query data [?name==''].{name:name,topic_id:\\topic-id\\} --output table```2. Create a JSON file to be used when creating the Event Rule. Replace topic id, display name, description and compartment OCID.```{ actions: { actions: [ { actionType: ONS, isEnabled: true, topicId: }] }, condition:{\\eventType\\:[\\com.oraclecloud.virtualnetwork.changeroutetablecompartment\\,\\com.oraclecloud.virtualnetwork.createroutetable\\,\\com.oraclecloud.virtualnetwork.deleteroutetable\\,\\com.oraclecloud.virtualnetwork.updateroutetable\\],\\data\\:{}}, displayName: , description: , isEnabled: true, compartmentId: }```3. Create the actual event rule```oci events rule create --from-json file://event_rule.json```4. Note in the JSON returned that it lists the parameters specified in the JSON file provided and that there is an OCID provided for the Event Rule",
+ "AuditProcedure": "**From Console:**1. Go to the Events Service page: [https://cloud.oracle.com/events/rules](https://cloud.oracle.com/events/rules)2. Select the `Compartment` that hosts the rules3. Find and click the `Rule` that handles `Route Table` Changes (if any)4. Click the `Edit Rule` button and verify that the `RuleConditions` section contains a condition for the Service `Networking` and Event Types: `Route Table – Change Compartment`, `Route Table – Create`, ` Route Table - Delete` and `Route Table - Update`5. Verify that in the `Actions` section the Action Type contains: `Notifications` and that a valid `Topic` is referenced.**From CLI:**1. Find the OCID of the specific Event Rule based on Display Name and Compartment OCID```oci events rule list --compartment-id --query data [?\\display-name\\==''].{id:id} --output table```2. List the details of a specific Event Rule based on the OCID of the rule.```oci events rule get --rule-id ```3. In the JSON output locate the Conditions key value pair and verify that the following Conditions are present:```com.oraclecloud.virtualnetwork.changeroutetablecompartmentcom.oraclecloud.virtualnetwork.createroutetablecom.oraclecloud.virtualnetwork.deleteroutetablecom.oraclecloud.virtualnetwork.updateroutetable```4. Verify the value of the `is-enabled` attribute is `true`5. In the JSON output verify that `actionType` is `ONS` and locate the `topic-id`6. Verify the correct topic is used by checking the topic name```oci ons topic get --topic-id --query data.{name:name} --output table```",
+ "AdditionalInformation": "'- The same Notification topic can be reused by many Event Rules.- The generated notification will include an eventID that can be used when querying the Audit Logs in case further investigation is required.",
+ "References": ""
+ }
+ ]
+ },
+ {
+ "Id": "4.10",
+ "Description": "Ensure a notification is configured for security list changes",
+ "Checks": [
+ "events_rule_security_list_changes"
+ ],
+ "Attributes": [
+ {
+ "Section": "4. Logging and Monitoring",
+ "Profile": "Level 1",
+ "AssessmentStatus": "Automated",
+ "Description": "It is recommended to setup an Event Rule and Notification that gets triggered when security lists are created, updated or deleted. Event Rules are compartment scoped and will detect events in child compartments, it is recommended to create the Event rule at the root compartment level.",
+ "RationaleStatement": "Security Lists control traffic flowing into and out of Subnets within a Virtual Cloud Network. Monitoring and alerting on changes to Security Lists will help in identifying changes to these security controls.",
+ "ImpactStatement": "There is no performance impact when enabling the above described features but depending on the amount of notifications sent per month there may be a cost associated.",
+ "RemediationProcedure": "**From Console:**1. Go to the `Events Service` page: [https://cloud.oracle.com/events/rules](https://cloud.oracle.com/events/rules)2. Select the `compartment` that should host the rule3. Click `Create Rule`4. Provide a `Display Name` and `Description`5. Create a Rule Condition by selecting `Networking` in the Service Name Drop-down and selecting `Security List – Change Compartment`, `Security List – Create`, `Security List - Delete` and `Security List – Update`6. In the `Actions` section select `Notifications` as Action Type7. Select the `Compartment` that hosts the Topic to be used.8. Select the `Topic` to be used9. Optionally add Tags to the Rule10. Click `Create Rule`**From CLI:**1. Find the `topic-id` of the topic the Event Rule should use for sending Notifications by using the topic `name` and `Compartment OCID````oci ons topic list --compartment-id --all --query data [?name==''].{name:name,topic_id:\\topic-id\\} --output table```2. Create a JSON file to be used when creating the Event Rule. Replace topic-id, display name, description and compartment OCID.```{ actions: { actions: [ { actionType: ONS, isEnabled: true, topicId: }] }, condition:{\\eventType\\:[\\com.oraclecloud.virtualnetwork.changesecuritylistcompartment\\,\\com.oraclecloud.virtualnetwork.createsecuritylist\\,\\com.oraclecloud.virtualnetwork.deletesecuritylist\\,\\com.oraclecloud.virtualnetwork.updatesecuritylist\\],\\data\\:{}}, displayName: , description: , isEnabled: true, compartmentId: }```3. Create the actual event rule```oci events rule create --from-json file://event_rule.json```4. Note in the JSON returned that it lists the parameters specified in the JSON file provided and that there is an OCID provided for the Event Rule",
+ "AuditProcedure": "**From Console:**1. Go to the Events Service page: [https://cloud.oracle.com/events/rules](https://cloud.oracle.com/events/rules)2. Select the `Compartment` that hosts the rules3. Find and click the `Rule` that handles `Security List` Changes (if any)4. Click the `Edit Rule` button and verify that the `RuleConditions` section contains a condition for the Service `Networking` and Event Types: `Security List – Change Compartment`, `Security List – Create`, `Security List - Delete` and `Security List – Update`5. Verify that in the `Actions` section the Action Type contains: `Notifications` and that a valid `Topic` is referenced.**From CLI:**1. Find the OCID of the specific Event Rule based on Display Name and Compartment OCID```oci events rule list --compartment-id --query data [?\\display-name\\==''].{id:id} --output table```2. List the details of a specific Event Rule based on the OCID of the rule.```oci events rule get --rule-id ```3. In the JSON output locate the Conditions key value pair and verify that the following Conditions are present:```com.oraclecloud.virtualnetwork.changesecuritylistcompartmentcom.oraclecloud.virtualnetwork.createsecuritylistcom.oraclecloud.virtualnetwork.deletesecuritylistcom.oraclecloud.virtualnetwork.updatesecuritylist```4. Verify the value of the `is-enabled` attribute is `true`5. In the JSON output verify that `actionType` is `ONS` and locate the `topic-id`6. Verify the correct topic is used by checking the topic name```oci ons topic get --topic-id --query data.{name:name} --output table```",
+ "AdditionalInformation": "'- The same Notification topic can be reused by many Event Rules.- The generated notification will include an eventID that can be used when querying the Audit Logs in case further investigation is required.",
+ "References": ""
+ }
+ ]
+ },
+ {
+ "Id": "4.11",
+ "Description": "Ensure a notification is configured for network security group changes",
+ "Checks": [
+ "events_rule_network_security_group_changes"
+ ],
+ "Attributes": [
+ {
+ "Section": "4. Logging and Monitoring",
+ "Profile": "Level 1",
+ "AssessmentStatus": "Automated",
+ "Description": "It is recommended to setup an Event Rule and Notification that gets triggered when network security groups are created, updated or deleted. Event Rules are compartment scoped and will detect events in child compartments, it is recommended to create the Event rule at the root compartment level.",
+ "RationaleStatement": "Network Security Groups control traffic flowing between Virtual Network Cards attached to Compute instances. Monitoring and alerting on changes to Network Security Groups will help in identifying changes these security controls.",
+ "ImpactStatement": "There is no performance impact when enabling the above described features but depending on the amount of notifications sent per month there may be a cost associated.",
+ "RemediationProcedure": "**From Console:**1. Go to the `Events Service` page: [https://cloud.oracle.com/events/rules](https://cloud.oracle.com/events/rules)2. Select the `compartment` that should host the rule3. Click `Create Rule`4. Provide a `Display Name` and `Description`5. Create a Rule Condition by selecting `Networking` in the Service Name Drop-down and selecting `Network Security Group – Change Compartment`, `Network Security Group – Create`, `Network Security Group - Delete` and `Network Security Group – Update`6. In the `Actions` section select `Notifications` as Action Type7. Select the `Compartment` that hosts the Topic to be used.8. Select the `Topic` to be used9. Optionally add Tags to the Rule10. Click `Create Rule`**From CLI:**1. Find the `topic-id` of the topic the Event Rule should use for sending Notifications by using the topic `name` and `Compartment OCID````oci ons topic list --compartment-id --all --query data [?name==''].{name:name,topic_id:\\topic-id\\} --output table```2. Create a JSON file to be used when creating the Event Rule. Replace topic id, display name, description and compartment OCID.```{ actions: { actions: [ { actionType: ONS, isEnabled: true, topicId: } ] }, condition:{\\eventType\\:[\\com.oraclecloud.virtualnetwork.changenetworksecuritygroupcompartment\\,\\com.oraclecloud.virtualnetwork.createnetworksecuritygroup\\,\\com.oraclecloud.virtualnetwork.deletenetworksecuritygroup\\,\\com.oraclecloud.virtualnetwork.updatenetworksecuritygroup\\],\\data\\:{}}, displayName: , description: , isEnabled: true, compartmentId: }```3. Create the actual event rule```oci events rule create --from-json file://event_rule.json```4. Note in the JSON returned that it lists the parameters specified in the JSON file provided and that there is an OCID provided for the Event Rule",
+ "AuditProcedure": "**From Console:**1. Go to the Events Service page: [https://cloud.oracle.com/events/rules](https://cloud.oracle.com/events/rules)2. Select the `Compartment` that hosts the rules3. Find and click the `Rule` that handles `Network Security Group` Changes (if any)4. Click the `Edit Rule` button and verify that the `RuleConditions` section contains a condition for the Service `Networking` and Event Types: `Network Security Group – Change Compartment`, `Network Security Group – Create`, `Network Security Group - Delete` and `Network Security Group – Update`5. Verify that in the `Actions` section the Action Type contains: `Notifications` and that a valid `Topic` is referenced.**From CLI:**1. Find the OCID of the specific Event Rule based on Display Name and Compartment OCID```oci events rule list --compartment-id --query data [?\\display-name\\==''].{id:id} --output table```2. List the details of a specific Event Rule based on the OCID of the rule.```oci events rule get --rule-id ```3. In the JSON output locate the Conditions key value pair and verify that the following conditions are present:```com.oraclecloud.virtualnetwork.changenetworksecuritygroupcompartmentcom.oraclecloud.virtualnetwork.createnetworksecuritygroupcom.oraclecloud.virtualnetwork.deletenetworksecuritygroupcom.oraclecloud.virtualnetwork.updatenetworksecuritygroup```4. Verify the value of the `is-enabled` attribute is `true`5. In the JSON output verify that `actionType` is `ONS` and locate the `topic-id`6. Verify the correct topic is used by checking the topic name```oci ons topic get --topic-id --query data.{name:name} --output table```",
+ "AdditionalInformation": "'- The same Notification topic can be reused by many Event Rules.- The generated notification will include an eventID that can be used when querying the Audit Logs in case further investigation is required.",
+ "References": ""
+ }
+ ]
+ },
+ {
+ "Id": "4.12",
+ "Description": "Ensure a notification is configured for changes to network gateways",
+ "Checks": [
+ "events_rule_network_gateway_changes"
+ ],
+ "Attributes": [
+ {
+ "Section": "4. Logging and Monitoring",
+ "Profile": "Level 1",
+ "AssessmentStatus": "Automated",
+ "Description": "It is recommended to setup an Event Rule and Notification that gets triggered when Network Gateways are created, updated, deleted, attached, detached, or moved. This recommendation includes Internet Gateways, Dynamic Routing Gateways, Service Gateways, Local Peering Gateways, and NAT Gateways. Event Rules are compartment scoped and will detect events in child compartments, it is recommended to create the Event rule at the root compartment level.",
+ "RationaleStatement": "Network Gateways act as routers between VCNs and the Internet, Oracle Services Networks, other VCNS, and on-premise networks.Monitoring and alerting on changes to Network Gateways will help in identifying changes to the security posture.",
+ "ImpactStatement": "There is no performance impact when enabling the above described features but depending on the amount of notifications sent per month there may be a cost associated.",
+ "RemediationProcedure": "**From Console:**1. Go to the `Events Service` page: [https://cloud.oracle.com/events/rules](https://cloud.oracle.com/events/rules)2. Select the `compartment` that should host the rule3. Click `Create Rule`4. Provide a `Display Name` and `Description`5. Create a Rule Condition by selecting `Networking` in the Service Name Drop-down and selecting:```DRG – CreateDRG – DeleteDRG – UpdateDRG Attachment – CreateDRG Attachment – DeleteDRG Attachment – UpdateInternet Gateway – CreateInternet Gateway – DeleteInternet Gateway – UpdateInternet Gateway – Change CompartmentLocal Peering Gateway – CreateLocal Peering Gateway – Delete EndLocal Peering Gateway – UpdateLocal Peering Gateway – Change CompartmentNAT Gateway – CreateNAT Gateway – DeleteNAT Gateway – UpdateNAT Gateway – Change CompartmentService Gateway – CreateService Gateway – Delete EndService Gateway – UpdateService Gateway – Attach ServiceService Gateway – Detach ServiceService Gateway – Change Compartment```6. In the `Actions` section select `Notifications` as Action Type7. Select the `Compartment` that hosts the Topic to be used.8. Select the `Topic` to be used9. Optionally add Tags to the Rule10. Click `Create Rule`**From CLI:**1. Find the `topic-id` of the topic the Event Rule should use for sending Notifications by using the topic `name` and `Compartment OCID````oci ons topic list --compartment-id --all --query data [?name==''].{name:name,topic_id:\\topic-id\\} --output table```2. Create a JSON file to be used when creating the Event Rule. Replace topic id, display name, description and compartment OCID.```{ actions: { actions: [ { actionType: ONS, isEnabled: true, topicId: } ] }, condition:{\\eventType\\:[\\com.oraclecloud.virtualnetwork.createdrg\\,\\com.oraclecloud.virtualnetwork.deletedrg\\,\\com.oraclecloud.virtualnetwork.updatedrg\\,\\com.oraclecloud.virtualnetwork.createdrgattachment\\,\\com.oraclecloud.virtualnetwork.deletedrgattachment\\,\\com.oraclecloud.virtualnetwork.updatedrgattachment\\,\\com.oraclecloud.virtualnetwork.changeinternetgatewaycompartment\\,\\com.oraclecloud.virtualnetwork.createinternetgateway\\,\\com.oraclecloud.virtualnetwork.deleteinternetgateway\\,\\com.oraclecloud.virtualnetwork.updateinternetgateway\\,\\com.oraclecloud.virtualnetwork.changelocalpeeringgatewaycompartment\\,\\com.oraclecloud.virtualnetwork.createlocalpeeringgateway\\,\\com.oraclecloud.virtualnetwork.deletelocalpeeringgateway.end\\,\\com.oraclecloud.virtualnetwork.updatelocalpeeringgateway\\,\\com.oraclecloud.natgateway.changenatgatewaycompartment\\,\\com.oraclecloud.natgateway.createnatgateway\\,\\com.oraclecloud.natgateway.deletenatgateway\\,\\com.oraclecloud.natgateway.updatenatgateway\\,\\com.oraclecloud.servicegateway.attachserviceid\\,\\com.oraclecloud.servicegateway.changeservicegatewaycompartment\\,\\com.oraclecloud.servicegateway.createservicegateway\\,\\com.oraclecloud.servicegateway.deleteservicegateway.end\\,\\com.oraclecloud.servicegateway.detachserviceid\\,\\com.oraclecloud.servicegateway.updateservicegateway\\],\\data\\:{}}, displayName: , description: , isEnabled: true, compartmentId: }```3. Create the actual event rule```oci events rule create --from-json file://event_rule.json```4. Note in the JSON returned that it lists the parameters specified in the JSON file provided and that there is an OCID provided for the Event Rule",
+ "AuditProcedure": "**From Console:**1. Go to the Events Service page: [https://cloud.oracle.com/events/rules](https://cloud.oracle.com/events/rules)2. Select the `Compartment` that hosts the rules3. Find and click the `Rule` that handles `Network Gateways` Changes (if any)4. Click the `Edit Rule` button and verify that the `RuleConditions` section contains a condition for the Service `Networking` and Event Types: ```DRG – CreateDRG – DeleteDRG – UpdateDRG Attachment – CreateDRG Attachment – DeleteDRG Attachment – UpdateInternet Gateway – CreateInternet Gateway – DeleteInternet Gateway – UpdateInternet Gateway – Change CompartmentLocal Peering Gateway – CreateLocal Peering Gateway – Delete EndLocal Peering Gateway – UpdateLocal Peering Gateway – Change CompartmentNAT Gateway – CreateNAT Gateway – DeleteNAT Gateway – UpdateNAT Gateway – Change CompartmentService Gateway – CreateService Gateway – Delete EndService Gateway – UpdateService Gateway – Attach ServiceService Gateway – Detach ServiceService Gateway – Change Compartment```5. Verify that in the `Actions` section the Action Type contains: `Notifications` and that a valid `Topic` is referenced.**From CLI:**1. Find the OCID of the specific Event Rule based on Display Name and Compartment OCID```oci events rule list --compartment-id --query data [?\\display-name\\==''].{id:id} --output table```2. List the details of a specific Event Rule based on the OCID of the rule.```oci events rule get --rule-id ```3. In the JSON output locate the Conditions key value pair and verify that the following Conditions are present:```com.oraclecloud.virtualnetwork.createdrgcom.oraclecloud.virtualnetwork.deletedrgcom.oraclecloud.virtualnetwork.updatedrgcom.oraclecloud.virtualnetwork.createdrgattachmentcom.oraclecloud.virtualnetwork.deletedrgattachmentcom.oraclecloud.virtualnetwork.updatedrgattachmentcom.oraclecloud.virtualnetwork.changeinternetgatewaycompartmentcom.oraclecloud.virtualnetwork.createinternetgatewaycom.oraclecloud.virtualnetwork.deleteinternetgatewaycom.oraclecloud.virtualnetwork.updateinternetgatewaycom.oraclecloud.virtualnetwork.changelocalpeeringgatewaycompartmentcom.oraclecloud.virtualnetwork.createlocalpeeringgatewaycom.oraclecloud.virtualnetwork.deletelocalpeeringgateway.endcom.oraclecloud.virtualnetwork.updatelocalpeeringgatewaycom.oraclecloud.natgateway.changenatgatewaycompartmentcom.oraclecloud.natgateway.createnatgatewaycom.oraclecloud.natgateway.deletenatgatewaycom.oraclecloud.natgateway.updatenatgatewaycom.oraclecloud.servicegateway.attachserviceidcom.oraclecloud.servicegateway.changeservicegatewaycompartmentcom.oraclecloud.servicegateway.createservicegatewaycom.oraclecloud.servicegateway.deleteservicegateway.endcom.oraclecloud.servicegateway.detachserviceidcom.oraclecloud.servicegateway.updateservicegateway```4. Verify the value of the `is-enabled` attribute is `true`5. In the JSON output verify that `actionType` is `ONS` and locate the `topic-id`6. Verify the correct topic is used by checking the topic name```oci ons topic get --topic-id --query data.{name:name} --output table```",
+ "AdditionalInformation": "'- The same Notification topic can be reused by many Event Rules.- The generated notification will include an eventID that can be used when querying the Audit Logs in case further investigation is required.",
+ "References": ""
+ }
+ ]
+ },
+ {
+ "Id": "4.13",
+ "Description": "Ensure VCN flow logging is enabled for all subnets",
+ "Checks": [
+ "network_vcn_subnet_flow_logs_enabled"
+ ],
+ "Attributes": [
+ {
+ "Section": "4. Logging and Monitoring",
+ "Profile": "Level 2",
+ "AssessmentStatus": "Automated",
+ "Description": "VCN flow logs record details about traffic that has been accepted or rejected based on the security list rule.",
+ "RationaleStatement": "Enabling VCN flow logs enables you to monitor traffic flowing within your virtual network and can be used to detect anomalous traffic.",
+ "ImpactStatement": "Enabling VCN flow logs will not affect the performance of your virtual network but it will generate additional use of object storage that should be controlled via object lifecycle management.By default, VCN flow logs are stored for 30 days in object storage. Users can specify a longer retention period.",
+ "RemediationProcedure": "**From Console:**First, if a Capture filter has not already been created, create a Capture Filter by the following steps:1. Go to the Network Command Center page (https://cloud.oracle.com/networking/network-command-center)2. Click 'Capture filters'3. Click 'Create Capture filter'4. Type a name for the Capture filter in the Name box.5. Select 'Flow log capture filter'6. For `Sample rating` select `100%`7. Scroll to `Rules`8. For `Traffic disposition` select `All`9. For `Include/Exclude` select `Include`10. Level `Source IPv4 CIDR or IPv6 prefix` and `Destination IPv4 CIDR or IPv6 prefix` empty11. For `IP protocol` select `Include`12. Click `Create Capture filter`Second, enable VCN flow logging for your VCN or subnet(s) by the following steps:1. Go to the Logs page (https://cloud.oracle.com/logging/logs)2. Click the `Enable Service Log` button in the middle of the screen.3. Select the relevant resource compartment.4. Select `Virtual Cloud Networks - Flow logs` from the Service drop down menu.5. Select the relevant resource level from the resource drop down menu either `VCN` or `subnet`.5. Select the relevant resource from the resource drop down menu.6. Select the from the Log Category drop down menu that either `Flow Logs - subnet records` or `Flow Logs - vcn records`.7. Select the Capture filter from above7. Type a name for your flow logs in the Log Name text box.7. Select the Compartment for the Log Location8. Select the Log Group for the Log Location or Click `Create New Group` to create a new log group8. Click the Enable Log button in the lower left-hand corner.",
+ "AuditProcedure": "**From Console (For Logging enabled Flow logs):**1. Go to the Virtual Cloud Network (VCN) page (https://cloud.oracle.com/networking/vcns)2. Select the Compartment 3. Click on the name of each VCN4. Click on each subnet within the VCN5. Under Resources click on Logs or the Monitoring tab6. Verify that there is a log enabled for the subnet7. Click the `Log Name`8. Verify `Flowlogs Capture Filter` is set to `No filter (collecting all logs)`9. If there is a Capture filter click the 'Capture Filter Name'10. Click `Edit`11. Verify Sampling rate is `100%`12. Click `Cancel`13. Verify there is a in the Rules list that is: `Enabled, Traffic disposition: All, Include/Exclude: Include, Source CIDR: Any, Destination CIDR: Any, IP Protocol: All`**From Console (For Network Command Center Enabled Flow logs):**1. Go to the Network Command Center page (https://cloud.oracle.com/networking/network-command-center)2. Click on Flow Logs3. Click on the Flow log `Name`4. Click `Edit`5. Verify Sampling rate is `100%` 6. Click `Cancel`7. Verify there is a in the Rules list that is: `Enabled, Traffic disposition: All, Include/Exclude: Include, Source CIDR: Any, Destination CIDR: Any, IP Protocol: All`",
+ "AdditionalInformation": "",
+ "References": "https://docs.oracle.com/en/solutions/oci-aggregate-logs-siem/index.html#GUID-601E052A-8A8E-466B-A8A8-2BBBD3B80B6D"
+ }
+ ]
+ },
+ {
+ "Id": "4.14",
+ "Description": "Ensure Cloud Guard is enabled in the root compartment of the tenancy",
+ "Checks": [
+ "cloudguard_enabled"
+ ],
+ "Attributes": [
+ {
+ "Section": "4. Logging and Monitoring",
+ "Profile": "Level 1",
+ "AssessmentStatus": "Automated",
+ "Description": "Cloud Guard detects misconfigured resources and insecure activity within a tenancy and provides security administrators with the visibility to resolve these issues. Upon detection, Cloud Guard can suggest, assist, or take corrective actions to mitigate these issues. Cloud Guard should be enabled in the root compartment of your tenancy with the default configuration, activity detectors and responders.",
+ "RationaleStatement": "Cloud Guard provides an automated means to monitor a tenancy for resources that are configured in an insecure manner as well as risky network activity from these resources.",
+ "ImpactStatement": "There is no performance impact when enabling the above described features, but additional IAM policies will be required.",
+ "RemediationProcedure": "**From Console:**1. Type `Cloud Guard` into the Search box at the top of the Console.2. Click `Cloud Guard` from the Services submenu.3. Click `Enable Cloud Guard`.4. Click `Create Policy`.5. Click `Next`.6. Under `Reporting Region`, select a region.7. Under `Compartments To Monitor`, choose `Select Compartment`.8. Under `Select Compartments`, select the `root` compartment.9. Under `Configuration Detector Recipe`, select `OCI Configuration Detector Recipe (Oracle Managed)`.10. Under `Activity Detector Recipe`, select `OCI Activity Detector Recipe (Oracle Managed)`.11. Click `Enable`.**From CLI:**1. Create OCI IAM Policy for Cloud Guard```oci iam policy create --compartment-id '' --name 'CloudGuardPolicies' --description 'Cloud Guard Access Policy' --statements '[ allow service cloudguard to read vaults in tenancy, allow service cloudguard to read keys in tenancy, allow service cloudguard to read compartments in tenancy, allow service cloudguard to read tenancies in tenancy, allow service cloudguard to read audit-events in tenancy, allow service cloudguard to read compute-management-family in tenancy, allow service cloudguard to read instance-family in tenancy, allow service cloudguard to read virtual-network-family in tenancy, allow service cloudguard to read volume-family in tenancy, allow service cloudguard to read database-family in tenancy, allow service cloudguard to read object-family in tenancy, allow service cloudguard to read load-balancers in tenancy, allow service cloudguard to read users in tenancy, allow service cloudguard to read groups in tenancy, allow service cloudguard to read policies in tenancy, allow service cloudguard to read dynamic-groups in tenancy, allow service cloudguard to read authentication-policies in tenancy ]'```2. Enable Cloud Guard in root compartment```oci cloud-guard configuration update --reporting-region '' --compartment-id '' --status 'ENABLED'```",
+ "AuditProcedure": "**From Console:**1. Type `Cloud Guard` into the Search box at the top of the Console.2. Click `Cloud Guard` from the Services submenu.3. View if `Cloud Guard` is enabled**From CLI:**1. Retrieve the `Cloud Guard` status from the console```oci cloud-guard configuration get --compartment-id --query 'data.status'```2. Ensure the returned value is ENABLED`",
+ "AdditionalInformation": "",
+ "References": "https://docs.oracle.com/en-us/iaas/Content/General/Concepts/regions.htm"
+ }
+ ]
+ },
+ {
+ "Id": "4.15",
+ "Description": "Ensure a notification is configured for Oracle Cloud Guard problems detected",
+ "Checks": [
+ "events_rule_cloudguard_problems"
+ ],
+ "Attributes": [
+ {
+ "Section": "4. Logging and Monitoring",
+ "Profile": "Level 1",
+ "AssessmentStatus": "Automated",
+ "Description": "Cloud Guard detects misconfigured resources and insecure activity within a tenancy and provides security administrators with the visibility to resolve these issues. Upon detection, Cloud Guard generates a Problem. It is recommended to setup an Event Rule and Notification that gets triggered when Oracle Cloud Guard Problems are created, dismissed or remediated. Event Rules are compartment scoped and will detect events in child compartments. It is recommended to create the Event rule at the root compartment level.",
+ "RationaleStatement": "Cloud Guard provides an automated means to monitor a tenancy for resources that are configured in an insecure manner as well as risky network activity from these resources. Monitoring and alerting on Problems detected by Cloud Guard will help in identifying changes to the security posture.",
+ "ImpactStatement": "There is no performance impact when enabling the above described features but depending on the amount of notifications sent per month there may be a cost associated.",
+ "RemediationProcedure": "**From Console:**1. Go to the Events Service page: [https://cloud.oracle.com/events/rules](https://cloud.oracle.com/events/rules)1. Select the compartment that should host the rule1. Click Create Rule1. Provide a Display Name and Description1. Create a Rule Condition by selecting Cloud Guard in the Service Name Drop-down and selecting: `Detected – Problem`, `Remediated – Problem`, and `Dismissed - Problem`1. In the Actions section select Notifications as Action Type1. Select the Compartment that hosts the Topic to be used.1. Select the Topic to be used1. Optionally add Tags to the Rule1. Click Create Rule**From CLI:**1. Find the topic-id of the topic the Event Rule should use for sending Notifications by using the topic name and Compartment OCID```oci ons topic list --compartment-id= --all --query data [?name==''].{name:name,topic_id:\\topic-id\\} --output table```1. Create a JSON file to be used when creating the Event Rule. Replace topic id, display name, description and compartment OCID.```{ actions: { actions: [ { actionType: ONS, isEnabled: true, topicId: }] }, condition:{\\eventType\\:[\\ com.oraclecloud.cloudguard.problemdetected\\,\\ com.oraclecloud.cloudguard.problemdismissed\\,\\ com.oraclecloud.cloudguard.problemremediated\\],\\data\\:{}}, displayName: , description: , isEnabled: true, compartmentId: compartment OCID}```1. Create the actual event rule```oci events rule create --from-json file://event_rule.json```1. Note in the JSON returned that it lists the parameters specified in the JSON file provided and that there is an OCID provided for the Event Rule",
+ "AuditProcedure": "**From Console:**1. Go to the Events Service page: [https://cloud.oracle.com/events/rules](https://cloud.oracle.com/events/rules)1. Select the Compartment that hosts the rules1. Find and click the Rule that handles Cloud Guard Changes (if any)1. Click the Edit Rule button and verify that the RuleConditions section contains a condition for the Service Cloud Guard and Event Types: Detected – Problem, Remediated – Problem, and Dismissed - Problem1. Verify that in the Actions section the Action Type contains: Notifications and that a valid Topic is referenced.**From CLI:**1. Find the OCID of the specific Event Rule based on Display Name and Compartment OCID```oci events rule list --compartment-id= --query data [?\\display-name\\==''].{id:id} --output table```1. List the details of a specific Event Rule based on the OCID of the rule.1. In the JSON output locate the Conditions key-value pair and verify that the following Conditions are present: ```com.oraclecloud.cloudguard.problemdetected,com.oraclecloud.cloudguard.problemdismissed,com.oraclecloud.cloudguard.problemremediated```1. Verify the value of the is-enabled attribute is true1. In the JSON output verify that actionType is ONS and locate the topic-id1. Verify the correct topic is used by checking the topic name```oci ons topic get --topic-id= --query data.{name:name} --output table```",
+ "AdditionalInformation": "'- Your tenancy might have a different Cloud Reporting region than your home region.- The same Notification topic can be reused by many Event Rules.- The generated notification will include an eventID that can be used when querying the Audit Logs in case further investigation is required.",
+ "References": "https://docs.oracle.com/en-us/iaas/cloud-guard/using/export-notifs-config.htm"
+ }
+ ]
+ },
+ {
+ "Id": "4.16",
+ "Description": "Ensure customer created Customer Managed Key (CMK) is rotated at least annually",
+ "Checks": [
+ "kms_key_rotation_enabled"
+ ],
+ "Attributes": [
+ {
+ "Section": "4. Logging and Monitoring",
+ "Profile": "Level 1",
+ "AssessmentStatus": "Automated",
+ "Description": "Oracle Cloud Infrastructure Vault securely stores master encryption keys that protect your encrypted data. You can use the Vault service to rotate keys to generate new cryptographic material. Periodically rotating keys limits the amount of data encrypted by one key version.",
+ "RationaleStatement": "Rotating keys annually limits the data encrypted under one key version. Key rotation thereby reduces the risk in case a key is ever compromised.",
+ "ImpactStatement": "",
+ "RemediationProcedure": "**From Console:**1. Login into OCI Console.2. Select `Identity & Security` from the Services menu.3. Select `Vault`.4. Click on the individual Vault under the Name heading.5. Click on the menu next to the time created.6. Click `Rotate Key`**From CLI:**1. Execute the following:```oci kms management key rotate --key-id --endpoint ```",
+ "AuditProcedure": "**From Console:**1. Login into OCI Console.2. Select `Identity & Security` from the Services menu.3. Select `Vault`.4. Click on the individual Vault under the Name heading.5. Ensure the date of each Master Encryption key under the `Created` column of the Master Encryption key is no more than 365 days old, and that the key is in the `ENABLED` state6. Repeat for all Vaults in all compartments**From CLI:**1. Execute the following for each Vault in each compartment```oci kms management key list --compartment-id '' --endpoint '' --all --query data[*].[\\time-created\\,\\display-name\\,\\lifecycle-state\\]```2. Ensure the date of the Master Encryption key is no more than 365 days old and is also in the `ENABLED` state.",
+ "AdditionalInformation": "",
+ "References": ""
+ }
+ ]
+ },
+ {
+ "Id": "4.17",
+ "Description": "Ensure write level Object Storage logging is enabled for all buckets",
+ "Checks": [
+ "objectstorage_bucket_logging_enabled"
+ ],
+ "Attributes": [
+ {
+ "Section": "4. Logging and Monitoring",
+ "Profile": "Level 2",
+ "AssessmentStatus": "Automated",
+ "Description": "Object Storage write logs will log all write requests made to objects in a bucket.",
+ "RationaleStatement": "Enabling Object Storage write logging ensures the `requestAction` property will show values like `PUT`, `POST`, or `DELETE`, providing increased visibility into changes made to objects within buckets.",
+ "ImpactStatement": "Enabling object storage write logging does not impact object storage performance, but will consume additional storage for the logs themselves. By default, logs are retained for 30 days, but users may configure longer retention periods. To manage costs, implement object lifecycle policies to remove unneeded logs as appropriate.",
+ "RemediationProcedure": "**From Console:**1. Log in to the OCI Console.2. Go to [Object Storage Buckets](https://cloud.oracle.com/object-storage/buckets).3. Click the name of the bucket to configure.4. In the Resource menu, click `Monitoring`.5. Scroll to the `Logs` section.6. Find `Write Access Events` and click the three dots `...` at the end of the row.7. Click `Enable Log`.8. Choose an existing log group or select `Create new group`.9. Configure the log name.10. Set a desired log retention period (in months).11. Click `Enable log`.**From CLI:***If a log group does not exist:*1. Create a log group:```shoci logging log-group create --compartment-id --display-name --description ```2. Check work request status:```shoci logging work-request get --work-request-id ```Wait until status is `SUCCEEDED`.*To enable write logging for your bucket(s):*3. Get the Log Group OCID:```shoci logging log-group list --compartment-id --query \"data[?\\display-name==''].id\" --raw-output```4. Create `config.json` with the following content (update all placeholders):```json{ \"compartment-id\": \"\", \"source\": { \"resource\": \"\", \"service\": \"ObjectStorage\", \"source-type\": \"OCISERVICE\", \"category\": \"write\" }}```5. Create the service log:```shoci logging log create --log-group-id --display-name --log-type SERVICE --is-enabled TRUE --configuration file://config.json```6. Confirm creation with work request id:```shoci logging work-request get --work-request-id ```Look for status `SUCCEEDED`.",
+ "AuditProcedure": "**From Console:**1. Log in to the OCI Console.2. Go to [Object Storage Buckets](https://cloud.oracle.com/object-storage/buckets).3. Click on a bucket's name.4. Select `Monitoring` from the Resource menu.5. Scroll to `Logs` and ensure the `Status` for `Write Access Events` is `Active`.**From CLI:**1. List all buckets in the compartment:```shoci os bucket list --compartment-id ```2. Find the Log Group OCID:```shoci logging log-group list --compartment-id --query \"data[?\\display-name=='']\"```3. List logs associated with the specific bucket:```shoci logging log list --log-group-id --query \"data[?configuration.source.resource=='']\"```4. Ensure a log entry exists for the target bucket's name.",
+ "AdditionalInformation": "",
+ "References": ""
+ }
+ ]
+ },
+ {
+ "Id": "4.18",
+ "Description": "Ensure a notification is configured for Local OCI User Authentication",
+ "Checks": [
+ "events_rule_local_user_authentication"
+ ],
+ "Attributes": [
+ {
+ "Section": "4. Logging and Monitoring",
+ "Profile": "Level 1",
+ "AssessmentStatus": "Automated",
+ "Description": "It is recommended that an Event Rule and Notification be set up when a user in the via OCI local authentication. Event Rules are compartment-scoped and will detect events in child compartments. This Event rule is required to be created at the root compartment level.",
+ "RationaleStatement": "Users should rarely use OCI local authenticated and be authenticated via organizational standard Identity providers, not local credentials. Access in this matter would represent a break glass activity and should be monitored to see if changes made impact the security posture.",
+ "ImpactStatement": "There is no performance impact when enabling the above-described features but depending on the amount of notifications sent per month there may be a cost associated.",
+ "RemediationProcedure": "From Console:1. Go to the Events Service page: [https://cloud.oracle.com/events/rules](https://cloud.oracle.com/events/rules)2. Select the `Root compartment` that should host the rule3. Click `Create Rule`4. Provide a `Display Name` and `Description`5. Create a Rule Condition by selecting `Identity SignOn` in the Service Name Drop-down and selecting `Interactive Login`6. In the `Actions` section select `Notifications` as Action Type7. Select the `Compartment` that hosts the Topic to be used.8. Select the `Topic` to be used9. Optionally add Tags to the Rule10. Click `Create Rule`From CLI:1. Find the `topic-id` of the topic the Event Rule should use for sending notifications by using the topic `name` and `Tenancy OCID````oci ons topic list --compartment-id --all --query data [?name==''].{name:name,topic_id:\\topic-id\\} --output table```2. Create a JSON file to be used when creating the Event Rule. Replace topic id, display name, description and compartment OCID.```{ actions: { actions: [ { actionType: ONS, isEnabled: true, topicId: }] }, condition:{\\eventType\\:[\\com.oraclecloud.identitysignon.interactivelogin\\,data\\:{}}, displayName: , description: , isEnabled: true, compartmentId: }```3. Create the actual event rule```oci events rule create --from-json file://event_rule.json```4. Note in the JSON returned that it lists the parameters specified in the JSON file provided and that there is an OCID provided for the Event Rule",
+ "AuditProcedure": "From Console:1. Go to the Events Service page: [https://cloud.oracle.com/events/rules](https://cloud.oracle.com/events/rules)2. Select the `Root Compartment `that hosts the rules3. Click the `Rule` that handles `Identity SignOn` Changes (if any)4. Click the `Edit Rule` button and verify that the `RuleCondition`s section contains a condition `Event Type` for the Service `Identity SignOn` and Event Types: `Interactive Login `5. On the Action Type contains: `Notifications` and that a valid Topic is referenced.From CLI:1. Find the OCID of the specific Event Rule based on Display Name and Tenancy OCID```oci events rule list --compartment-id --query data [?\\display-name\\==''].{id:id} --output table```2. List the details of a specific Event Rule based on the OCID of the rule.```oci events rule get --rule-id ```3. In the JSON output locate the Conditions key value pair and verify that the following Conditions are present:```com.oraclecloud.identitysignon.interactivelogin```4. Verify the value of the `is-enabled` attribute is `true`5. In the JSON output verify that `actionType` is `ONS` and locate the `topic-id`6. Verify the correct topic is used by checking the topic name```oci ons topic get --topic-id --query data.{name:name} --output table```",
+ "AdditionalInformation": "'- The same Notification topic can be reused by many Event Rules.- The generated notification will include an eventID that can be used when querying the Audit Logs in case further investigation is required.",
+ "References": "https://docs.oracle.com/en-us/iaas/Content/Security/Reference/iam_security_topic-IAM_Federation.htm#IAM_Federation"
+ }
+ ]
+ },
+ {
+ "Id": "5.1.1",
+ "Description": "Ensure no Object Storage buckets are publicly visible",
+ "Checks": [
+ "objectstorage_bucket_not_publicly_accessible"
+ ],
+ "Attributes": [
+ {
+ "Section": "5. Storage",
+ "SubSection": "5.1 Object Storage",
+ "Profile": "Level 1",
+ "AssessmentStatus": "Automated",
+ "Description": "A bucket is a logical container for storing objects. It is associated with a single compartment that has policies that determine what action a user can perform on a bucket and on all the objects in the bucket. By Default a newly created bucket is private. It is recommended that no bucket be publicly accessible.",
+ "RationaleStatement": "Removing unfettered reading of objects in a bucket reduces an organization's exposure to data loss.",
+ "ImpactStatement": "For updating an existing bucket, care should be taken to ensure objects in the bucket can be accessed through either IAM policies or pre-authenticated requests.",
+ "RemediationProcedure": "**From Console:**1. Follow the audit procedure above. 2. For each `bucket` in the returned results, click the Bucket `Display Name`3. Click `Edit Visibility`3. Select `Private`4. Click `Save Changes`**From CLI:**1. Follow the audit procedure2. For each of the `buckets` identified, execute the following command:```oci os bucket update --bucket-name --public-access-type NoPublicAccess```",
+ "AuditProcedure": "**From Console:**1. Login into the OCI Console2. Click in the search bar at the top of the screen.3. Type `Advanced Resource Query` and click `enter`.4. Click the `Advanced Resource Query` button in the upper right of the screen.5. Enter the following query in the query box:```querybucket resourceswhere (publicAccessType == 'ObjectRead') || (publicAccessType == 'ObjectReadWithoutList')```6. Ensure query returns no results**From CLI:**1. Execute the following command:```oci search resource structured-search --query-text query bucket resourceswhere (publicAccessType == 'ObjectRead') || (publicAccessType == 'ObjectReadWithoutList')```2. Ensure query returns no results**Cloud Guard**To Enable Cloud Guard Auditing:Ensure Cloud Guard is enabled in the root compartment of the tenancy. For more information about enabling Cloud Guard, please look at the instructions included in Recommendation 3.15. **From Console:**1. Type `Cloud Guard` into the Search box at the top of the Console. 2. Click `Cloud Guard` from the “Services” submenu.3. Click `Detector Recipes` in the Cloud Guard menu.4. Click `OCI Configuration Detector Recipe (Oracle Managed)` under the Recipe Name column.5. Find Bucket is public in the Detector Rules column.6. Verify that the Bucket is public Detector Rule is Enabled.**From CLI:**1. Verify the Bucket is public Detector Rule in Cloud Guard is enabled to generate Problems if Object Storage Buckets are configured to be accessible over the public Internet with the following command:```oci cloud-guard detector-recipe-detector-rule get --detector-recipe-id --detector-rule-id BUCKET_IS_PUBLIC```",
+ "AdditionalInformation": "",
+ "References": "https://docs.oracle.com/en-us/iaas/Content/Object/Tasks/managingbuckets.htm"
+ }
+ ]
+ },
+ {
+ "Id": "5.1.2",
+ "Description": "Ensure Object Storage Buckets are encrypted with a Customer Managed Key (CMK)",
+ "Checks": [
+ "objectstorage_bucket_encrypted_with_cmk"
+ ],
+ "Attributes": [
+ {
+ "Section": "5. Storage",
+ "SubSection": "5.1 Object Storage",
+ "Profile": "Level 2",
+ "AssessmentStatus": "Automated",
+ "Description": "Oracle Object Storage buckets support encryption with a Customer Managed Key (CMK). By default, Object Storage buckets are encrypted with an Oracle managed key.",
+ "RationaleStatement": "Encryption of Object Storage buckets with a Customer Managed Key (CMK) provides an additional level of security on your data by allowing you to manage your own encryption key lifecycle management for the bucket.",
+ "ImpactStatement": "Encrypting with a Customer Managed Keys requires a Vault and a Customer Master Key. In addition, you must authorize Object Storage service to use keys on your behalf.Required Policy:```Allow service objectstorage-, to use keys in compartment where target.key.id = ''```",
+ "RemediationProcedure": "**From Console:**1. Go to [https://cloud.oracle.com/object-storage/buckets](https://cloud.oracle.com/object-storage/buckets)1. Click on an individual bucket under the Name heading.1. Click `Assign` next to `Encryption Key: Oracle managed key`.1. Select a `Vault`1. Select a `Master Encryption Key`1. Click `Assign`**From CLI:**1. Execute the following command```oci os bucket update --bucket-name --kms-key-id ```",
+ "AuditProcedure": "**From Console:**1. Go to [https://cloud.oracle.com/object-storage/buckets](https://cloud.oracle.com/object-storage/buckets)1. Click on an individual bucket under the Name heading.1. Ensure that the `Encryption Key` is not set to `Oracle managed key`.1. Repeat for each compartment**From CLI:**1. Execute the following command```oci os bucket get --bucket-name ```2. Ensure `kms-key-id` is not `null`**Cloud Guard**To Enable Cloud Guard Auditing:Ensure Cloud Guard is enabled in the root compartment of the tenancy. For more information about enabling Cloud Guard, please look at the instructions included in Recommendation 3.15. **From Console:**1. Type `Cloud Guard` into the Search box at the top of the Console. 2. Click `Cloud Guard` from the “Services” submenu.3. Click `Detector Recipes` in the Cloud Guard menu.4. Click `OCI Configuration Detector Recipe (Oracle Managed)` under the Recipe Name column.5. Find Object Storage bucket is encrypted with Oracle-managed key in the Detector Rules column.6. Verify that the Object Storage bucket is encrypted with Oracle-managed key Detector Rule is Enabled.**From CLI:**1. Verify the Object Storage bucket is encrypted with Oracle-managed key Detector Rule in Cloud Guard is enabled to generate Problems if Object Storage Buckets are configured without a customer managed key with the following command:```oci cloud-guard detector-recipe-detector-rule get --detector-recipe-id --detector-rule-id BUCKET_ENCRYPTED_WITH_ORACLE_MANAGED_KEY```",
+ "AdditionalInformation": "",
+ "References": "https://docs.oracle.com/en/solutions/oci-best-practices/protect-data-rest1.html#GUID-9C0F713E-4C67-43C6-80CA-525A6AB221F1:https://docs.oracle.com/en-us/iaas/Content/Object/Tasks/encryption.htm"
+ }
+ ]
+ },
+ {
+ "Id": "5.1.3",
+ "Description": "Ensure Versioning is Enabled for Object Storage Buckets",
+ "Checks": [
+ "objectstorage_bucket_versioning_enabled"
+ ],
+ "Attributes": [
+ {
+ "Section": "5. Storage",
+ "SubSection": "5.1 Object Storage",
+ "Profile": "Level 2",
+ "AssessmentStatus": "Automated",
+ "Description": "A bucket is a logical container for storing objects. Object versioning is enabled at the bucket level and is disabled by default upon creation. Versioning directs Object Storage to automatically create an object version each time a new object is uploaded, an existing object is overwritten, or when an object is deleted. You can enable object versioning at bucket creation time or later.",
+ "RationaleStatement": "Versioning object storage buckets provides for additional integrity of your data. Management of data integrity is critical to protecting and accessing protected data. Some customers want to identify object storage buckets without versioning in order to apply their own data lifecycle protection and management policy.",
+ "ImpactStatement": "",
+ "RemediationProcedure": "**From Console:**1. Follow the audit procedure above.2. For each bucket in the returned results, click the Bucket Display Name3. Click `Edit` next to `Object Versioning: Disabled`4. Click `Enable Versioning`**From CLI:**1. Follow the audit procedure2. For each of the buckets identified, execute the following command:```oci os bucket update --bucket-name --versioning Enabled```",
+ "AuditProcedure": "**From Console:**1. Login to OCI Console.2. Select `Storage` from the Services menu.3. Select `Buckets` from under the `Object Storage & Archive Storage` section.4. Click on an individual bucket under the Name heading.5. Ensure that the `Object Versioning` is set to Enabled.6. Repeat for each compartment**From CLI:**1. Execute the following command:```for region in $(oci iam region-subscription list --all | jq -r '.data[] | .region-name')do echo Enumerating region $region for compid in $(oci iam compartment list --include-root --compartment-id-in-subtree TRUE 2>/dev/null | jq -r '.data[] | .id') do echo Enumerating compartment $compid for bkt in $(oci os bucket list --compartment-id $compid --region $region 2>/dev/null | jq -r '.data[] | .name') do output=$(oci os bucket get --bucket-name $bkt --region $region 2>/dev/null | jq -r '.data | select(.versioning == Disabled).name') if [ ! -z $output ]; then echo $output; fi done donedone```2. Ensure no results are returned.",
+ "AdditionalInformation": "",
+ "References": "https://docs.oracle.com/en-us/iaas/Content/Object/Tasks/usingversioning.htm:https://docs.oracle.com/en-us/iaas/api/#/en/objectstorage/20160918/Bucket/GetBucket"
+ }
+ ]
+ },
+ {
+ "Id": "5.2.1",
+ "Description": "Ensure Block Volumes are encrypted with Customer Managed Keys (CMK)",
+ "Checks": [
+ "blockstorage_block_volume_encrypted_with_cmk"
+ ],
+ "Attributes": [
+ {
+ "Section": "5. Storage",
+ "SubSection": "5.2 Block Volumes",
+ "Profile": "Level 2",
+ "AssessmentStatus": "Automated",
+ "Description": "Oracle Cloud Infrastructure Block Volume service lets you dynamically provision and manage block storage volumes. By default, the Oracle service manages the keys that encrypt block volumes. Block Volumes can also be encrypted using a customer managed key.Terminated Block Volumes cannot be recovered and any data on a terminated volume is permanently lost. However, Block Volumes can exist in a terminated state within the OCI Portal and CLI for some time after deleting. As such, any Block Volumes in this state should not be considered when assessing this policy.",
+ "RationaleStatement": "Encryption of block volumes provides an additional level of security for your data. Management of encryption keys is critical to protecting and accessing protected data. Customers should identify block volumes encrypted with Oracle service managed keys in order to determine if they want to manage the keys for certain volumes and then apply their own key lifecycle management to the selected block volumes.",
+ "ImpactStatement": "Encrypting with a Customer Managed Key requires a Vault and a Customer Master Key. In addition, you must authorize the Block Volume service to use the keys you create.Required IAM Policy:```Allow service blockstorage to use keys in compartment