diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 74e9332e34..b953610fa1 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1,6 +1,28 @@ +# SDK /* @prowler-cloud/sdk -/.github/ @prowler-cloud/sdk -prowler @prowler-cloud/sdk @prowler-cloud/detection-and-remediation -tests @prowler-cloud/sdk @prowler-cloud/detection-and-remediation -api @prowler-cloud/api -ui @prowler-cloud/ui \ No newline at end of file +/prowler/ @prowler-cloud/sdk @prowler-cloud/detection-and-remediation +/tests/ @prowler-cloud/sdk @prowler-cloud/detection-and-remediation +/dashboard/ @prowler-cloud/sdk +/docs/ @prowler-cloud/sdk +/examples/ @prowler-cloud/sdk +/util/ @prowler-cloud/sdk +/contrib/ @prowler-cloud/sdk +/permissions/ @prowler-cloud/sdk +/codecov.yml @prowler-cloud/sdk @prowler-cloud/api + +# API +/api/ @prowler-cloud/api + +# UI +/ui/ @prowler-cloud/ui + +# AI +/mcp_server/ @prowler-cloud/ai + +# Platform +/.github/ @prowler-cloud/platform +/Makefile @prowler-cloud/platform +/kubernetes/ @prowler-cloud/platform +**/Dockerfile* @prowler-cloud/platform +**/docker-compose*.yml @prowler-cloud/platform +**/docker-compose*.yaml @prowler-cloud/platform diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index fa4c805d85..fcba29ca1f 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -3,6 +3,41 @@ description: Create a report to help us improve labels: ["bug", "status/needs-triage"] body: + - type: checkboxes + id: search + attributes: + label: Issue search + options: + - label: I have searched the existing issues and this bug has not been reported yet + required: true + - type: dropdown + id: component + attributes: + label: Which component is affected? + multiple: true + options: + - Prowler CLI/SDK + - Prowler API + - Prowler UI + - Prowler Dashboard + - Prowler MCP Server + - Documentation + - Other + validations: + required: true + - type: dropdown + id: provider + attributes: + label: Cloud Provider (if applicable) + multiple: true + options: + - AWS + - Azure + - GCP + - Kubernetes + - GitHub + - Microsoft 365 + - Not applicable - type: textarea id: reproduce attributes: @@ -78,6 +113,15 @@ body: prowler --version validations: required: true + - type: input + id: python-version + attributes: + label: Python version + description: Which Python version are you using? + placeholder: |- + python --version + validations: + required: true - type: input id: pip-version attributes: diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index 3ba13e0cec..6e7c21013b 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -1 +1,11 @@ blank_issues_enabled: false +contact_links: + - name: 📖 Documentation + url: https://docs.prowler.com + about: Check our comprehensive documentation for guides and tutorials + - name: đŸ’Ŧ GitHub Discussions + url: https://github.com/prowler-cloud/prowler/discussions + about: Ask questions and discuss with the community + - name: 🌟 Prowler Community + url: https://goto.prowler.com/slack + about: Join our community for support and updates diff --git a/.github/ISSUE_TEMPLATE/feature-request.yml b/.github/ISSUE_TEMPLATE/feature-request.yml index 528723b717..0ba3557f38 100644 --- a/.github/ISSUE_TEMPLATE/feature-request.yml +++ b/.github/ISSUE_TEMPLATE/feature-request.yml @@ -3,6 +3,42 @@ description: Suggest an idea for this project labels: ["feature-request", "status/needs-triage"] body: + - type: checkboxes + id: search + attributes: + label: Feature search + options: + - label: I have searched the existing issues and this feature has not been requested yet + required: true + - type: dropdown + id: component + attributes: + label: Which component would this feature affect? + multiple: true + options: + - Prowler CLI/SDK + - Prowler API + - Prowler UI + - Prowler Dashboard + - Prowler MCP Server + - Documentation + - New component/Integration + validations: + required: true + - type: dropdown + id: provider + attributes: + label: Related to specific cloud provider? + multiple: true + options: + - AWS + - Azure + - GCP + - Kubernetes + - GitHub + - Microsoft 365 + - All providers + - Not provider-specific - type: textarea id: Problem attributes: @@ -19,6 +55,14 @@ body: description: A clear and concise description of what you want to happen. validations: required: true + - type: textarea + id: use-case + attributes: + label: Use case and benefits + description: Who would benefit from this feature and how? + placeholder: This would help security teams by... + validations: + required: true - type: textarea id: Alternatives attributes: diff --git a/.github/actions/setup-python-poetry/action.yml b/.github/actions/setup-python-poetry/action.yml new file mode 100644 index 0000000000..3b774262f9 --- /dev/null +++ b/.github/actions/setup-python-poetry/action.yml @@ -0,0 +1,71 @@ +name: 'Setup Python with Poetry' +description: 'Setup Python environment with Poetry and install dependencies' +author: 'Prowler' + +inputs: + python-version: + description: 'Python version to use' + required: true + working-directory: + description: 'Working directory for Poetry' + required: false + default: '.' + poetry-version: + description: 'Poetry version to install' + required: false + default: '2.1.1' + install-dependencies: + description: 'Install Python dependencies with Poetry' + required: false + default: 'true' + +runs: + using: 'composite' + steps: + - name: Replace @master with current branch in pyproject.toml + if: github.event_name == 'pull_request' && github.base_ref == 'master' + shell: bash + working-directory: ${{ inputs.working-directory }} + run: | + BRANCH_NAME="${GITHUB_HEAD_REF:-${GITHUB_REF_NAME}}" + echo "Using branch: $BRANCH_NAME" + sed -i "s|@master|@$BRANCH_NAME|g" pyproject.toml + + - name: Install poetry + shell: bash + run: | + python -m pip install --upgrade pip + pipx install poetry==${{ inputs.poetry-version }} + + - name: Update SDK resolved_reference to latest commit + if: github.event_name == 'push' && github.ref == 'refs/heads/master' + shell: bash + working-directory: ${{ inputs.working-directory }} + run: | + LATEST_COMMIT=$(curl -s "https://api.github.com/repos/prowler-cloud/prowler/commits/master" | jq -r '.sha') + echo "Latest commit hash: $LATEST_COMMIT" + sed -i '/url = "https:\/\/github\.com\/prowler-cloud\/prowler\.git"/,/resolved_reference = / { + s/resolved_reference = "[a-f0-9]\{40\}"/resolved_reference = "'"$LATEST_COMMIT"'"/ + }' poetry.lock + echo "Updated resolved_reference:" + grep -A2 -B2 "resolved_reference" poetry.lock + + - name: Update poetry.lock + shell: bash + working-directory: ${{ inputs.working-directory }} + run: poetry lock + + - name: Set up Python ${{ inputs.python-version }} + uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0 + with: + python-version: ${{ inputs.python-version }} + cache: 'poetry' + cache-dependency-path: ${{ inputs.working-directory }}/poetry.lock + + - name: Install Python dependencies + if: inputs.install-dependencies == 'true' + shell: bash + working-directory: ${{ inputs.working-directory }} + run: | + poetry install --no-root + poetry run pip list diff --git a/.github/actions/trivy-scan/action.yml b/.github/actions/trivy-scan/action.yml new file mode 100644 index 0000000000..91c4c4d332 --- /dev/null +++ b/.github/actions/trivy-scan/action.yml @@ -0,0 +1,152 @@ +name: 'Container Security Scan with Trivy' +description: 'Scans container images for vulnerabilities using Trivy and reports results' +author: 'Prowler' + +inputs: + image-name: + description: 'Container image name to scan' + required: true + image-tag: + description: 'Container image tag to scan' + required: true + default: ${{ github.sha }} + severity: + description: 'Severities to scan for (comma-separated)' + required: false + default: 'CRITICAL,HIGH,MEDIUM,LOW' + fail-on-critical: + description: 'Fail the build if critical vulnerabilities are found' + required: false + default: 'false' + upload-sarif: + description: 'Upload results to GitHub Security tab' + required: false + default: 'true' + create-pr-comment: + description: 'Create a comment on the PR with scan results' + required: false + default: 'true' + artifact-retention-days: + description: 'Days to retain the Trivy report artifact' + required: false + default: '2' + +outputs: + critical-count: + description: 'Number of critical vulnerabilities found' + value: ${{ steps.security-check.outputs.critical }} + high-count: + description: 'Number of high vulnerabilities found' + value: ${{ steps.security-check.outputs.high }} + total-count: + description: 'Total number of vulnerabilities found' + value: ${{ steps.security-check.outputs.total }} + +runs: + using: 'composite' + steps: + - name: Run Trivy vulnerability scan (SARIF) + if: inputs.upload-sarif == 'true' + uses: aquasecurity/trivy-action@b6643a29fecd7f34b3597bc6acb0a98b03d33ff8 # v0.33.1 + with: + image-ref: ${{ inputs.image-name }}:${{ inputs.image-tag }} + format: 'sarif' + output: 'trivy-results.sarif' + severity: 'CRITICAL,HIGH' + exit-code: '0' + + - name: Upload Trivy results to GitHub Security tab + if: inputs.upload-sarif == 'true' + uses: github/codeql-action/upload-sarif@3599b3baa15b485a2e49ef411a7a4bb2452e7f93 # v3.30.5 + with: + sarif_file: 'trivy-results.sarif' + category: 'trivy-container' + + - name: Run Trivy vulnerability scan (JSON) + uses: aquasecurity/trivy-action@b6643a29fecd7f34b3597bc6acb0a98b03d33ff8 # v0.33.1 + with: + image-ref: ${{ inputs.image-name }}:${{ inputs.image-tag }} + format: 'json' + output: 'trivy-report.json' + severity: ${{ inputs.severity }} + exit-code: '0' + + - name: Upload Trivy report artifact + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + if: always() + with: + name: trivy-scan-report-${{ inputs.image-name }} + path: trivy-report.json + retention-days: ${{ inputs.artifact-retention-days }} + + - name: Generate security summary + id: security-check + shell: bash + run: | + CRITICAL=$(jq '[.Results[]?.Vulnerabilities[]? | select(.Severity=="CRITICAL")] | length' trivy-report.json) + HIGH=$(jq '[.Results[]?.Vulnerabilities[]? | select(.Severity=="HIGH")] | length' trivy-report.json) + TOTAL=$(jq '[.Results[]?.Vulnerabilities[]?] | length' trivy-report.json) + + echo "critical=$CRITICAL" >> $GITHUB_OUTPUT + echo "high=$HIGH" >> $GITHUB_OUTPUT + echo "total=$TOTAL" >> $GITHUB_OUTPUT + + echo "### 🔒 Container Security Scan" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "**Image:** \`${{ inputs.image-name }}:${{ inputs.image-tag }}\`" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + echo "- 🔴 Critical: $CRITICAL" >> $GITHUB_STEP_SUMMARY + echo "- 🟠 High: $HIGH" >> $GITHUB_STEP_SUMMARY + echo "- **Total**: $TOTAL" >> $GITHUB_STEP_SUMMARY + + - name: Comment scan results on PR + if: inputs.create-pr-comment == 'true' && github.event_name == 'pull_request' + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 + env: + IMAGE_NAME: ${{ inputs.image-name }} + GITHUB_SHA: ${{ inputs.image-tag }} + SEVERITY: ${{ inputs.severity }} + with: + script: | + const comment = require('./.github/scripts/trivy-pr-comment.js'); + + // Unique identifier to find our comment + const marker = ''; + const body = marker + '\n' + comment; + + // Find existing comment + const { data: comments } = await github.rest.issues.listComments({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.issue.number, + }); + + const existingComment = comments.find(c => c.body?.includes(marker)); + + if (existingComment) { + // Update existing comment + await github.rest.issues.updateComment({ + owner: context.repo.owner, + repo: context.repo.repo, + comment_id: existingComment.id, + body: body + }); + console.log('✅ Updated existing Trivy scan comment'); + } else { + // Create new comment + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.issue.number, + body: body + }); + console.log('✅ Created new Trivy scan comment'); + } + + - name: Check for critical vulnerabilities + if: inputs.fail-on-critical == 'true' && steps.security-check.outputs.critical != '0' + shell: bash + run: | + echo "::error::Found ${{ steps.security-check.outputs.critical }} critical vulnerabilities" + echo "::warning::Please update packages or use a different base image" + exit 1 diff --git a/.github/codeql/api-codeql-config.yml b/.github/codeql/api-codeql-config.yml index 9ce26a3651..0925ea4a33 100644 --- a/.github/codeql/api-codeql-config.yml +++ b/.github/codeql/api-codeql-config.yml @@ -1,3 +1,12 @@ -name: "API - CodeQL Config" +name: 'API: CodeQL Config' paths: - - "api/" + - 'api/' + +paths-ignore: + - 'api/tests/**' + - 'api/**/__pycache__/**' + - 'api/**/migrations/**' + - 'api/**/*.md' + +queries: + - uses: security-and-quality diff --git a/.github/scripts/trivy-pr-comment.js b/.github/scripts/trivy-pr-comment.js new file mode 100644 index 0000000000..eb725b1af1 --- /dev/null +++ b/.github/scripts/trivy-pr-comment.js @@ -0,0 +1,102 @@ +const fs = require('fs'); + +// Configuration from environment variables +const REPORT_FILE = process.env.TRIVY_REPORT_FILE || 'trivy-report.json'; +const IMAGE_NAME = process.env.IMAGE_NAME || 'container-image'; +const GITHUB_SHA = process.env.GITHUB_SHA || 'unknown'; +const GITHUB_REPOSITORY = process.env.GITHUB_REPOSITORY || ''; +const GITHUB_RUN_ID = process.env.GITHUB_RUN_ID || ''; +const SEVERITY = process.env.SEVERITY || 'CRITICAL,HIGH,MEDIUM,LOW'; + +// Parse severities to scan +const scannedSeverities = SEVERITY.split(',').map(s => s.trim()); + +// Read and parse the Trivy report +const report = JSON.parse(fs.readFileSync(REPORT_FILE, 'utf-8')); + +let vulnCount = 0; +let vulnsByType = { CRITICAL: 0, HIGH: 0, MEDIUM: 0, LOW: 0 }; +let affectedPackages = new Set(); + +if (report.Results && Array.isArray(report.Results)) { + for (const result of report.Results) { + if (result.Vulnerabilities && Array.isArray(result.Vulnerabilities)) { + for (const vuln of result.Vulnerabilities) { + vulnCount++; + if (vulnsByType[vuln.Severity] !== undefined) { + vulnsByType[vuln.Severity]++; + } + if (vuln.PkgName) { + affectedPackages.add(vuln.PkgName); + } + } + } + } +} + +const shortSha = GITHUB_SHA.substring(0, 7); +const timestamp = new Date().toISOString().replace('T', ' ').substring(0, 19) + ' UTC'; + +// Severity icons and labels +const severityConfig = { + CRITICAL: { icon: '🔴', label: 'Critical' }, + HIGH: { icon: '🟠', label: 'High' }, + MEDIUM: { icon: '🟡', label: 'Medium' }, + LOW: { icon: 'đŸ”ĩ', label: 'Low' } +}; + +let comment = '## 🔒 Container Security Scan\n\n'; +comment += `**Image:** \`${IMAGE_NAME}:${shortSha}\`\n`; +comment += `**Last scan:** ${timestamp}\n\n`; + +if (vulnCount === 0) { + comment += '### ✅ No Vulnerabilities Detected\n\n'; + comment += 'The container image passed all security checks. No known CVEs were found.\n'; +} else { + comment += '### 📊 Vulnerability Summary\n\n'; + comment += '| Severity | Count |\n'; + comment += '|----------|-------|\n'; + + // Only show severities that were scanned + for (const severity of scannedSeverities) { + const config = severityConfig[severity]; + const count = vulnsByType[severity] || 0; + const isBold = (severity === 'CRITICAL' || severity === 'HIGH') && count > 0; + const countDisplay = isBold ? `**${count}**` : count; + comment += `| ${config.icon} ${config.label} | ${countDisplay} |\n`; + } + + comment += `| **Total** | **${vulnCount}** |\n\n`; + + if (affectedPackages.size > 0) { + comment += `**${affectedPackages.size}** package(s) affected\n\n`; + } + + if (vulnsByType.CRITICAL > 0) { + comment += '### âš ī¸ Action Required\n\n'; + comment += '**Critical severity vulnerabilities detected.** These should be addressed before merging:\n'; + comment += '- Review the detailed scan results\n'; + comment += '- Update affected packages to patched versions\n'; + comment += '- Consider using a different base image if updates are unavailable\n\n'; + } else if (vulnsByType.HIGH > 0) { + comment += '### âš ī¸ Attention Needed\n\n'; + comment += '**High severity vulnerabilities found.** Please review and plan remediation:\n'; + comment += '- Assess the risk and exploitability\n'; + comment += '- Prioritize updates in the next maintenance cycle\n\n'; + } else { + comment += '### â„šī¸ Review Recommended\n\n'; + comment += 'Medium/Low severity vulnerabilities found. Consider addressing during regular maintenance.\n\n'; + } +} + +comment += '---\n'; +comment += '📋 **Resources:**\n'; + +if (GITHUB_REPOSITORY && GITHUB_RUN_ID) { + comment += `- [Download full report](https://github.com/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}) (see artifacts)\n`; +} + +comment += '- [View in Security tab](https://github.com/' + (GITHUB_REPOSITORY || 'repository') + '/security/code-scanning)\n'; +comment += '- Scanned with [Trivy](https://github.com/aquasecurity/trivy)\n'; + +module.exports = comment; diff --git a/.github/workflows/api-codeql.yml b/.github/workflows/api-codeql.yml index d0211c4caa..e9af830156 100644 --- a/.github/workflows/api-codeql.yml +++ b/.github/workflows/api-codeql.yml @@ -1,36 +1,34 @@ -# For most projects, this workflow file will not need changing; you simply need -# to commit it to your repository. -# -# You may wish to alter this file to override the set of languages analyzed, -# or to provide custom queries or build logic. -# -# ******** NOTE ******** -# We have attempted to detect the languages in your repository. Please check -# the `language` matrix defined below to confirm you have the correct set of -# supported CodeQL languages. -# -name: API - CodeQL +name: 'API: CodeQL' on: push: branches: - - "master" - - "v5.*" + - 'master' + - 'v5.*' paths: - - "api/**" + - 'api/**' + - '.github/workflows/api-codeql.yml' + - '.github/codeql/api-codeql-config.yml' pull_request: branches: - - "master" - - "v5.*" + - 'master' + - 'v5.*' paths: - - "api/**" + - 'api/**' + - '.github/workflows/api-codeql.yml' + - '.github/codeql/api-codeql-config.yml' schedule: - cron: '00 12 * * *' +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + jobs: analyze: - name: Analyze + name: CodeQL Security Analysis runs-on: ubuntu-latest + timeout-minutes: 30 permissions: actions: read contents: read @@ -39,21 +37,20 @@ jobs: strategy: fail-fast: false matrix: - language: [ 'python' ] - # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support + language: + - 'python' steps: - - name: Checkout repository - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + - name: Checkout repository + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - # Initializes the CodeQL tools for scanning. - - name: Initialize CodeQL - uses: github/codeql-action/init@3599b3baa15b485a2e49ef411a7a4bb2452e7f93 # v3.30.5 - with: - languages: ${{ matrix.language }} - config-file: ./.github/codeql/api-codeql-config.yml + - name: Initialize CodeQL + uses: github/codeql-action/init@3599b3baa15b485a2e49ef411a7a4bb2452e7f93 # v3.30.5 + with: + languages: ${{ matrix.language }} + config-file: ./.github/codeql/api-codeql-config.yml - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@3599b3baa15b485a2e49ef411a7a4bb2452e7f93 # v3.30.5 - with: - category: "/language:${{matrix.language}}" + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@3599b3baa15b485a2e49ef411a7a4bb2452e7f93 # v3.30.5 + with: + category: '/language:${{ matrix.language }}' diff --git a/.github/workflows/api-pull-request.yml b/.github/workflows/api-pull-request.yml index e899af8f32..1266ce78c9 100644 --- a/.github/workflows/api-pull-request.yml +++ b/.github/workflows/api-pull-request.yml @@ -1,20 +1,30 @@ -name: API - Pull Request +name: 'API: Pull Request' on: push: branches: - - "master" - - "v5.*" + - 'master' + - 'v5.*' paths: - - ".github/workflows/api-pull-request.yml" - - "api/**" + - '.github/workflows/api-pull-request.yml' + - 'api/**' + - '!api/docs/**' + - '!api/README.md' + - '!api/CHANGELOG.md' pull_request: branches: - - "master" - - "v5.*" + - 'master' + - 'v5.*' paths: - - ".github/workflows/api-pull-request.yml" - - "api/**" + - '.github/workflows/api-pull-request.yml' + - 'api/**' + - '!api/docs/**' + - '!api/README.md' + - '!api/CHANGELOG.md' + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true env: POSTGRES_HOST: localhost @@ -29,21 +39,94 @@ env: VALKEY_DB: 0 API_WORKING_DIR: ./api IMAGE_NAME: prowler-api - IGNORE_FILES: | - api/docs/** - api/README.md - api/CHANGELOG.md jobs: - test: + code-quality: + if: github.repository == 'prowler-cloud/prowler' runs-on: ubuntu-latest + timeout-minutes: 30 + permissions: + contents: read strategy: matrix: - python-version: ["3.12"] + python-version: + - '3.12' + defaults: + run: + working-directory: ./api + + steps: + - name: Checkout repository + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + + - name: Setup Python with Poetry + uses: ./.github/actions/setup-python-poetry + with: + python-version: ${{ matrix.python-version }} + working-directory: ./api + + - name: Poetry check + run: poetry check --lock + + - name: Ruff lint + run: poetry run ruff check . --exclude contrib + + - name: Ruff format + run: poetry run ruff format --check . --exclude contrib + + - name: Pylint + run: poetry run pylint --disable=W,C,R,E -j 0 -rn -sn src/ + + security-scans: + if: github.repository == 'prowler-cloud/prowler' + runs-on: ubuntu-latest + timeout-minutes: 15 + permissions: + contents: read + strategy: + matrix: + python-version: + - '3.12' + defaults: + run: + working-directory: ./api + + steps: + - name: Checkout repository + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + + - name: Setup Python with Poetry + uses: ./.github/actions/setup-python-poetry + with: + python-version: ${{ matrix.python-version }} + working-directory: ./api + + - name: Bandit + run: poetry run bandit -q -lll -x '*_test.py,./contrib/' -r . + + - name: Safety + # 76352, 76353, 77323 come from SDK, but they cannot upgrade it yet. It does not affect API + # TODO: Botocore needs urllib3 1.X so we need to ignore these vulnerabilities 77744,77745. Remove this once we upgrade to urllib3 2.X + run: poetry run safety check --ignore 70612,66963,74429,76352,76353,77323,77744,77745 + + - name: Vulture + run: poetry run vulture --exclude "contrib,tests,conftest.py" --min-confidence 100 . + + tests: + if: github.repository == 'prowler-cloud/prowler' + runs-on: ubuntu-latest + timeout-minutes: 30 + permissions: + contents: read + strategy: + matrix: + python-version: + - '3.12' + defaults: + run: + working-directory: ./api - # Service containers to run with `test` services: - # Label used to access the service container postgres: image: postgres env: @@ -52,7 +135,6 @@ jobs: POSTGRES_USER: ${{ env.POSTGRES_USER }} POSTGRES_PASSWORD: ${{ env.POSTGRES_PASSWORD }} POSTGRES_DB: ${{ env.POSTGRES_DB }} - # Set health checks to wait until postgres has started ports: - 5432:5432 options: >- @@ -66,7 +148,6 @@ jobs: VALKEY_HOST: ${{ env.VALKEY_HOST }} VALKEY_PORT: ${{ env.VALKEY_PORT }} VALKEY_DB: ${{ env.VALKEY_DB }} - # Set health checks to wait until postgres has started ports: - 6379:6379 options: >- @@ -76,158 +157,72 @@ jobs: --health-retries 5 steps: - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + - name: Checkout repository + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - - name: Test if changes are in not ignored paths - id: are-non-ignored-files-changed - uses: tj-actions/changed-files@24d32ffd492484c1d75e0c0b894501ddb9d30d62 # v47.0.0 - with: - files: | - api/** - .github/workflows/api-pull-request.yml - files_ignore: ${{ env.IGNORE_FILES }} - - - name: Replace @master with current branch in pyproject.toml - Only for pull requests to `master` - working-directory: ./api - if: steps.are-non-ignored-files-changed.outputs.any_changed == 'true' && github.event_name == 'pull_request' && github.base_ref == 'master' - run: | - BRANCH_NAME="${GITHUB_HEAD_REF:-${GITHUB_REF_NAME}}" - echo "Using branch: $BRANCH_NAME" - sed -i "s|@master|@$BRANCH_NAME|g" pyproject.toml - - - name: Install poetry - working-directory: ./api - if: steps.are-non-ignored-files-changed.outputs.any_changed == 'true' - run: | - python -m pip install --upgrade pip - pipx install poetry==2.1.1 - - - name: Update SDK's poetry.lock resolved_reference to latest commit - Only for push events to `master` - working-directory: ./api - if: steps.are-non-ignored-files-changed.outputs.any_changed == 'true' && github.event_name == 'push' && github.ref == 'refs/heads/master' - run: | - # Get the latest commit hash from the prowler-cloud/prowler repository - LATEST_COMMIT=$(curl -s "https://api.github.com/repos/prowler-cloud/prowler/commits/master" | jq -r '.sha') - echo "Latest commit hash: $LATEST_COMMIT" - - # Update the resolved_reference specifically for prowler-cloud/prowler repository - sed -i '/url = "https:\/\/github\.com\/prowler-cloud\/prowler\.git"/,/resolved_reference = / { - s/resolved_reference = "[a-f0-9]\{40\}"/resolved_reference = "'"$LATEST_COMMIT"'"/ - }' poetry.lock - - # Verify the change was made - echo "Updated resolved_reference:" - grep -A2 -B2 "resolved_reference" poetry.lock - - - name: Update poetry.lock - working-directory: ./api - if: steps.are-non-ignored-files-changed.outputs.any_changed == 'true' - run: | - poetry lock - - - name: Set up Python ${{ matrix.python-version }} - if: steps.are-non-ignored-files-changed.outputs.any_changed == 'true' - uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0 + - name: Setup Python with Poetry + uses: ./.github/actions/setup-python-poetry with: python-version: ${{ matrix.python-version }} - cache: "poetry" + working-directory: ./api - - name: Install dependencies - working-directory: ./api - if: steps.are-non-ignored-files-changed.outputs.any_changed == 'true' - run: | - poetry install --no-root - poetry run pip list - VERSION=$(curl --silent "https://api.github.com/repos/hadolint/hadolint/releases/latest" | \ - grep '"tag_name":' | \ - sed -E 's/.*"v([^"]+)".*/\1/' \ - ) && curl -L -o /tmp/hadolint "https://github.com/hadolint/hadolint/releases/download/v${VERSION}/hadolint-Linux-x86_64" \ - && chmod +x /tmp/hadolint - - - name: Poetry check - working-directory: ./api - if: steps.are-non-ignored-files-changed.outputs.any_changed == 'true' - run: | - poetry check --lock - - - name: Lint with ruff - working-directory: ./api - if: steps.are-non-ignored-files-changed.outputs.any_changed == 'true' - run: | - poetry run ruff check . --exclude contrib - - - name: Check Format with ruff - working-directory: ./api - if: steps.are-non-ignored-files-changed.outputs.any_changed == 'true' - run: | - poetry run ruff format --check . --exclude contrib - - - name: Lint with pylint - working-directory: ./api - if: steps.are-non-ignored-files-changed.outputs.any_changed == 'true' - run: | - poetry run pylint --disable=W,C,R,E -j 0 -rn -sn src/ - - - name: Bandit - working-directory: ./api - if: steps.are-non-ignored-files-changed.outputs.any_changed == 'true' - run: | - poetry run bandit -q -lll -x '*_test.py,./contrib/' -r . - - - name: Safety - working-directory: ./api - if: steps.are-non-ignored-files-changed.outputs.any_changed == 'true' - # 76352, 76353, 77323 come from SDK, but they cannot upgrade it yet. It does not affect API - # TODO: Botocore needs urllib3 1.X so we need to ignore these vulnerabilities 77744,77745. Remove this once we upgrade to urllib3 2.X - run: | - poetry run safety check --ignore 70612,66963,74429,76352,76353,77323,77744,77745 - - - name: Vulture - working-directory: ./api - if: steps.are-non-ignored-files-changed.outputs.any_changed == 'true' - run: | - poetry run vulture --exclude "contrib,tests,conftest.py" --min-confidence 100 . - - - name: Hadolint - working-directory: ./api - if: steps.are-non-ignored-files-changed.outputs.any_changed == 'true' - run: | - /tmp/hadolint Dockerfile --ignore=DL3013 - - - name: Test with pytest - working-directory: ./api - if: steps.are-non-ignored-files-changed.outputs.any_changed == 'true' - run: | - poetry run pytest --cov=./src/backend --cov-report=xml src/backend + - name: Run tests with pytest + run: poetry run pytest --cov=./src/backend --cov-report=xml src/backend - name: Upload coverage reports to Codecov - if: steps.are-non-ignored-files-changed.outputs.any_changed == 'true' uses: codecov/codecov-action@5a1091511ad55cbe89839c7260b706298ca349f7 # v5.5.1 env: CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} with: flags: api - test-container-build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - - name: Test if changes are in not ignored paths - id: are-non-ignored-files-changed - uses: tj-actions/changed-files@24d32ffd492484c1d75e0c0b894501ddb9d30d62 # v47.0.0 + dockerfile-lint: + if: github.repository == 'prowler-cloud/prowler' + runs-on: ubuntu-latest + timeout-minutes: 15 + permissions: + contents: read + + steps: + - name: Checkout repository + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + + - name: Lint Dockerfile with Hadolint + uses: hadolint/hadolint-action@2332a7b74a6de0dda2e2221d575162eba76ba5e5 # v3.3.0 with: - files: api/** - files_ignore: ${{ env.IGNORE_FILES }} + dockerfile: api/Dockerfile + ignore: DL3013 + + container-build-and-scan: + if: github.repository == 'prowler-cloud/prowler' + runs-on: ubuntu-latest + timeout-minutes: 30 + permissions: + contents: read + security-events: write + pull-requests: write + + steps: + - name: Checkout repository + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + - name: Set up Docker Buildx - if: steps.are-non-ignored-files-changed.outputs.any_changed == 'true' uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1 - - name: Build Container - if: steps.are-non-ignored-files-changed.outputs.any_changed == 'true' + + - name: Build container uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0 with: context: ${{ env.API_WORKING_DIR }} push: false - tags: ${{ env.IMAGE_NAME }}:latest - outputs: type=docker + load: true + tags: ${{ env.IMAGE_NAME }}:${{ github.sha }} cache-from: type=gha cache-to: type=gha,mode=max + + - name: Scan container with Trivy + uses: ./.github/actions/trivy-scan + with: + image-name: ${{ env.IMAGE_NAME }} + image-tag: ${{ github.sha }} + fail-on-critical: 'false' + severity: 'CRITICAL' diff --git a/.github/workflows/backport.yml b/.github/workflows/backport.yml index 2aa0a49c09..4fd1347f44 100644 --- a/.github/workflows/backport.yml +++ b/.github/workflows/backport.yml @@ -1,28 +1,35 @@ -name: Prowler - Automatic Backport +name: 'Tools: Backport' on: pull_request_target: - branches: ['master'] - types: ['labeled', 'closed'] + branches: + - 'master' + types: + - 'labeled' + - 'closed' + paths: + - '.github/workflows/backport.yml' + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number }} + cancel-in-progress: false env: - # The prefix of the label that triggers the backport must not contain the branch name - # so, for example, if the branch is 'master', the label should be 'backport-to-' BACKPORT_LABEL_PREFIX: backport-to- BACKPORT_LABEL_IGNORE: was-backported jobs: backport: - name: Backport PR if: github.event.pull_request.merged == true && !(contains(github.event.pull_request.labels.*.name, 'backport')) && !(contains(github.event.pull_request.labels.*.name, 'was-backported')) runs-on: ubuntu-latest + timeout-minutes: 15 permissions: - id-token: write - pull-requests: write contents: write + pull-requests: write + steps: - name: Check labels - id: preview_label_check + id: label_check uses: agilepathway/label-checker@c3d16ad512e7cea5961df85ff2486bb774caf3c5 # v1.6.65 with: allow_failure: true @@ -31,17 +38,17 @@ jobs: none_of: ${{ env.BACKPORT_LABEL_IGNORE }} repo_token: ${{ secrets.GITHUB_TOKEN }} - - name: Backport Action - if: steps.preview_label_check.outputs.label_check == 'success' + - name: Backport PR + if: steps.label_check.outputs.label_check == 'success' uses: sorenlouv/backport-github-action@ad888e978060bc1b2798690dd9d03c4036560947 # v9.5.1 with: github_token: ${{ secrets.PROWLER_BOT_ACCESS_TOKEN }} auto_backport_label_prefix: ${{ env.BACKPORT_LABEL_PREFIX }} - - name: Info log - if: ${{ success() && steps.preview_label_check.outputs.label_check == 'success' }} + - name: Display backport info log + if: success() && steps.label_check.outputs.label_check == 'success' run: cat ~/.backport/backport.info.log - - name: Debug log - if: ${{ failure() && steps.preview_label_check.outputs.label_check == 'success' }} + - name: Display backport debug log + if: failure() && steps.label_check.outputs.label_check == 'success' run: cat ~/.backport/backport.debug.log diff --git a/.github/workflows/conventional-commit.yml b/.github/workflows/conventional-commit.yml index ecaf651c34..c5ba446edf 100644 --- a/.github/workflows/conventional-commit.yml +++ b/.github/workflows/conventional-commit.yml @@ -1,24 +1,31 @@ -name: Prowler - Conventional Commit +name: 'Tools: Conventional Commit' on: pull_request: - types: - - "opened" - - "edited" - - "synchronize" branches: - - "master" - - "v3" - - "v4.*" - - "v5.*" + - 'master' + - 'v3' + - 'v4.*' + - 'v5.*' + types: + - 'opened' + - 'edited' + - 'synchronize' + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number }} + cancel-in-progress: true jobs: conventional-commit-check: runs-on: ubuntu-latest + timeout-minutes: 15 + permissions: + contents: read + pull-requests: read + steps: - - name: conventional-commit-check - id: conventional-commit-check + - name: Check PR title format uses: agenthunt/conventional-commit-checker-action@9e552d650d0e205553ec7792d447929fc78e012b # v2.0.0 with: - pr-title-regex: '^(feat|fix|docs|style|refactor|perf|test|chore|build|ci|revert)(\([^)]+\))?!?: .+' - \ No newline at end of file + pr-title-regex: '^(feat|fix|docs|style|refactor|perf|test|chore|build|ci|revert)(\([^)]+\))?!?: .+' diff --git a/.github/workflows/create-backport-label.yml b/.github/workflows/create-backport-label.yml index 3b485ec513..b4308156c7 100644 --- a/.github/workflows/create-backport-label.yml +++ b/.github/workflows/create-backport-label.yml @@ -1,67 +1,70 @@ -name: Prowler - Create Backport Label +name: 'Tools: Backport Label' on: release: - types: [published] + types: + - 'published' + +concurrency: + group: ${{ github.workflow }}-${{ github.event.release.tag_name }} + cancel-in-progress: false + +env: + BACKPORT_LABEL_PREFIX: backport-to- + BACKPORT_LABEL_COLOR: B60205 jobs: - create_label: + create-label: runs-on: ubuntu-latest + timeout-minutes: 15 permissions: - contents: write + contents: read issues: write + steps: - - name: Create backport label + - name: Create backport label for minor releases env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - RELEASE_TAG: ${{ github.event.release.tag_name }} - OWNER_REPO: ${{ github.repository }} + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | - VERSION_ONLY=${RELEASE_TAG#v} # Remove 'v' prefix if present (e.g., v3.2.0 -> 3.2.0) + RELEASE_TAG="${{ github.event.release.tag_name }}" + + if [ -z "$RELEASE_TAG" ]; then + echo "Error: No release tag provided" + exit 1 + fi + + echo "Processing release tag: $RELEASE_TAG" + + # Remove 'v' prefix if present (e.g., v3.2.0 -> 3.2.0) + VERSION_ONLY="${RELEASE_TAG#v}" # Check if it's a minor version (X.Y.0) - if [[ "$VERSION_ONLY" =~ ^[0-9]+\.[0-9]+\.0$ ]]; then - echo "Release ${RELEASE_TAG} (version ${VERSION_ONLY}) is a minor version. Proceeding to create backport label." + if [[ "$VERSION_ONLY" =~ ^([0-9]+)\.([0-9]+)\.0$ ]]; then + echo "Release $RELEASE_TAG (version $VERSION_ONLY) is a minor version. Proceeding to create backport label." - TWO_DIGIT_VERSION=${VERSION_ONLY%.0} # Extract X.Y from X.Y.0 (e.g., 5.6 from 5.6.0) + # Extract X.Y from X.Y.0 (e.g., 5.6 from 5.6.0) + MAJOR="${BASH_REMATCH[1]}" + MINOR="${BASH_REMATCH[2]}" + TWO_DIGIT_VERSION="${MAJOR}.${MINOR}" - FINAL_LABEL_NAME="backport-to-v${TWO_DIGIT_VERSION}" - FINAL_DESCRIPTION="Backport PR to the v${TWO_DIGIT_VERSION} branch" + LABEL_NAME="${BACKPORT_LABEL_PREFIX}v${TWO_DIGIT_VERSION}" + LABEL_DESC="Backport PR to the v${TWO_DIGIT_VERSION} branch" + LABEL_COLOR="$BACKPORT_LABEL_COLOR" - echo "Effective label name will be: ${FINAL_LABEL_NAME}" - echo "Effective description will be: ${FINAL_DESCRIPTION}" + echo "Label name: $LABEL_NAME" + echo "Label description: $LABEL_DESC" - # Check if the label already exists - STATUS_CODE=$(curl -s -o /dev/null -w "%{http_code}" -H "Authorization: token ${GITHUB_TOKEN}" "https://api.github.com/repos/${OWNER_REPO}/labels/${FINAL_LABEL_NAME}") - - if [ "${STATUS_CODE}" -eq 200 ]; then - echo "Label '${FINAL_LABEL_NAME}' already exists." - elif [ "${STATUS_CODE}" -eq 404 ]; then - echo "Label '${FINAL_LABEL_NAME}' does not exist. Creating it..." - # Prepare JSON data payload - JSON_DATA=$(printf '{"name":"%s","description":"%s","color":"B60205"}' "${FINAL_LABEL_NAME}" "${FINAL_DESCRIPTION}") - - CREATE_STATUS_CODE=$(curl -s -o /tmp/curl_create_response.json -w "%{http_code}" -X POST \ - -H "Accept: application/vnd.github.v3+json" \ - -H "Authorization: token ${GITHUB_TOKEN}" \ - --data "${JSON_DATA}" \ - "https://api.github.com/repos/${OWNER_REPO}/labels") - - CREATE_RESPONSE_BODY=$(cat /tmp/curl_create_response.json) - rm -f /tmp/curl_create_response.json - - if [ "$CREATE_STATUS_CODE" -eq 201 ]; then - echo "Label '${FINAL_LABEL_NAME}' created successfully." - else - echo "Error creating label '${FINAL_LABEL_NAME}'. Status: $CREATE_STATUS_CODE" - echo "Response: $CREATE_RESPONSE_BODY" - exit 1 - fi + # Check if label already exists + if gh label list --repo ${{ github.repository }} --limit 1000 | grep -q "^${LABEL_NAME}[[:space:]]"; then + echo "Label '$LABEL_NAME' already exists." else - echo "Error checking for label '${FINAL_LABEL_NAME}'. HTTP Status: ${STATUS_CODE}" - exit 1 + echo "Label '$LABEL_NAME' does not exist. Creating it..." + gh label create "$LABEL_NAME" \ + --description "$LABEL_DESC" \ + --color "$LABEL_COLOR" \ + --repo ${{ github.repository }} + echo "Label '$LABEL_NAME' created successfully." fi else - echo "Release ${RELEASE_TAG} (version ${VERSION_ONLY}) is not a minor version. Skipping backport label creation." - exit 0 + echo "Release $RELEASE_TAG (version $VERSION_ONLY) is not a minor version. Skipping backport label creation." fi diff --git a/.github/workflows/find-secrets.yml b/.github/workflows/find-secrets.yml index e7feaea43a..6428cf8f08 100644 --- a/.github/workflows/find-secrets.yml +++ b/.github/workflows/find-secrets.yml @@ -1,19 +1,33 @@ -name: Prowler - Find secrets +name: 'Tools: TruffleHog' -on: pull_request +on: + push: + branches: + - 'master' + - 'v5.*' + pull_request: + branches: + - 'master' + - 'v5.*' + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true jobs: - trufflehog: + scan-secrets: runs-on: ubuntu-latest + timeout-minutes: 15 + permissions: + contents: read + steps: - - name: Checkout + - name: Checkout repository uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 with: fetch-depth: 0 - - name: TruffleHog OSS - uses: trufflesecurity/trufflehog@466da5b0bb161144f6afca9afe5d57975828c410 # v3.90.8 + + - name: Scan for secrets with TruffleHog + uses: trufflesecurity/trufflehog@ad6fc8fb446b8fafbf7ea8193d2d6bfd42f45690 # v3.90.11 with: - path: ./ - base: ${{ github.event.repository.default_branch }} - head: HEAD - extra_args: --only-verified + extra_args: '--results=verified,unknown' diff --git a/.github/workflows/labeler.yml b/.github/workflows/labeler.yml index 9dfa8993a1..fad94177f7 100644 --- a/.github/workflows/labeler.yml +++ b/.github/workflows/labeler.yml @@ -1,17 +1,29 @@ -name: Prowler - PR Labeler +name: 'Tools: PR Labeler' on: - pull_request_target: - branches: - - "master" - - "v3" - - "v4.*" + pull_request_target: + branches: + - 'master' + - 'v5.*' + types: + - 'opened' + - 'reopened' + - 'synchronize' + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number }} + cancel-in-progress: true jobs: labeler: + runs-on: ubuntu-latest + timeout-minutes: 15 permissions: contents: read pull-requests: write - runs-on: ubuntu-latest + steps: - - uses: actions/labeler@634933edcd8ababfe52f92936142cc22ac488b1b # v6.0.1 + - name: Apply labels to PR + uses: actions/labeler@634933edcd8ababfe52f92936142cc22ac488b1b # v6.0.1 + with: + sync-labels: true diff --git a/api/CHANGELOG.md b/api/CHANGELOG.md index 13749d8b9e..bdbcdcda6d 100644 --- a/api/CHANGELOG.md +++ b/api/CHANGELOG.md @@ -14,6 +14,7 @@ All notable changes to the **Prowler API** are documented in this file. - Support for `passed_findings` and `total_findings` fields in compliance requirement overview for accurate Prowler ThreatScore calculation [(#8582)](https://github.com/prowler-cloud/prowler/pull/8582) - Database read replica support [(#8869)](https://github.com/prowler-cloud/prowler/pull/8869) - Support Common Cloud Controls for AWS, Azure and GCP [(#8000)](https://github.com/prowler-cloud/prowler/pull/8000) +- Add `provider_id__in` filter support to findings and findings severity overview endpoints [(#8951)](https://github.com/prowler-cloud/prowler/pull/8951) ### Changed - Now the MANAGE_ACCOUNT permission is required to modify or read user permissions instead of MANAGE_USERS [(#8281)](https://github.com/prowler-cloud/prowler/pull/8281) diff --git a/api/src/backend/api/filters.py b/api/src/backend/api/filters.py index ed706006e9..8552d30a64 100644 --- a/api/src/backend/api/filters.py +++ b/api/src/backend/api/filters.py @@ -765,6 +765,7 @@ class ComplianceOverviewFilter(FilterSet): class ScanSummaryFilter(FilterSet): inserted_at = DateFilter(field_name="inserted_at", lookup_expr="date") provider_id = UUIDFilter(field_name="scan__provider__id", lookup_expr="exact") + provider_id__in = UUIDInFilter(field_name="scan__provider__id", lookup_expr="in") provider_type = ChoiceFilter( field_name="scan__provider__provider", choices=Provider.ProviderChoices.choices ) diff --git a/api/src/backend/api/specs/v1.yaml b/api/src/backend/api/specs/v1.yaml index 3f0005726b..578da5f287 100644 --- a/api/src/backend/api/specs/v1.yaml +++ b/api/src/backend/api/specs/v1.yaml @@ -3611,6 +3611,16 @@ paths: schema: type: string format: uuid + - in: query + name: filter[provider_id__in] + schema: + type: array + items: + type: string + format: uuid + description: Multiple values may be separated by commas. + explode: false + style: form - in: query name: filter[provider_type] schema: @@ -3778,6 +3788,16 @@ paths: schema: type: string format: uuid + - in: query + name: filter[provider_id__in] + schema: + type: array + items: + type: string + format: uuid + description: Multiple values may be separated by commas. + explode: false + style: form - in: query name: filter[provider_type] schema: @@ -3980,6 +4000,16 @@ paths: schema: type: string format: uuid + - in: query + name: filter[provider_id__in] + schema: + type: array + items: + type: string + format: uuid + description: Multiple values may be separated by commas. + explode: false + style: form - in: query name: filter[provider_type] schema: diff --git a/api/src/backend/api/tests/test_views.py b/api/src/backend/api/tests/test_views.py index 1b1783cc5a..3f78ce7705 100644 --- a/api/src/backend/api/tests/test_views.py +++ b/api/src/backend/api/tests/test_views.py @@ -46,6 +46,7 @@ from api.models import ( SAMLConfiguration, SAMLToken, Scan, + ScanSummary, StateChoices, Task, TenantAPIKey, @@ -5766,6 +5767,171 @@ class TestOverviewViewSet: assert service1_data["attributes"]["muted"] == 1 assert service2_data["attributes"]["muted"] == 0 + def test_overview_findings_provider_id_in_filter( + self, authenticated_client, tenants_fixture, providers_fixture + ): + tenant = tenants_fixture[0] + provider1, provider2, *_ = providers_fixture + + scan1 = Scan.objects.create( + name="scan-one", + provider=provider1, + trigger=Scan.TriggerChoices.MANUAL, + state=StateChoices.COMPLETED, + tenant=tenant, + ) + scan2 = Scan.objects.create( + name="scan-two", + provider=provider2, + trigger=Scan.TriggerChoices.MANUAL, + state=StateChoices.COMPLETED, + tenant=tenant, + ) + + ScanSummary.objects.create( + tenant=tenant, + scan=scan1, + check_id="check-provider-one", + service="service-a", + severity="high", + region="region-a", + _pass=5, + fail=1, + muted=2, + total=8, + new=5, + changed=2, + unchanged=1, + fail_new=1, + fail_changed=0, + pass_new=3, + pass_changed=2, + muted_new=1, + muted_changed=1, + ) + + ScanSummary.objects.create( + tenant=tenant, + scan=scan2, + check_id="check-provider-two", + service="service-b", + severity="medium", + region="region-b", + _pass=2, + fail=3, + muted=1, + total=6, + new=3, + changed=2, + unchanged=1, + fail_new=2, + fail_changed=1, + pass_new=1, + pass_changed=1, + muted_new=1, + muted_changed=0, + ) + + single_response = authenticated_client.get( + reverse("overview-findings"), + {"filter[provider_id__in]": str(provider1.id)}, + ) + assert single_response.status_code == status.HTTP_200_OK + single_attributes = single_response.json()["data"]["attributes"] + assert single_attributes["pass"] == 5 + assert single_attributes["fail"] == 1 + assert single_attributes["muted"] == 2 + assert single_attributes["total"] == 8 + + combined_response = authenticated_client.get( + reverse("overview-findings"), + {"filter[provider_id__in]": f"{provider1.id},{provider2.id}"}, + ) + assert combined_response.status_code == status.HTTP_200_OK + combined_attributes = combined_response.json()["data"]["attributes"] + assert combined_attributes["pass"] == 7 + assert combined_attributes["fail"] == 4 + assert combined_attributes["muted"] == 3 + assert combined_attributes["total"] == 14 + + def test_overview_findings_severity_provider_id_in_filter( + self, authenticated_client, tenants_fixture, providers_fixture + ): + tenant = tenants_fixture[0] + provider1, provider2, *_ = providers_fixture + + scan1 = Scan.objects.create( + name="severity-scan-one", + provider=provider1, + trigger=Scan.TriggerChoices.MANUAL, + state=StateChoices.COMPLETED, + tenant=tenant, + ) + scan2 = Scan.objects.create( + name="severity-scan-two", + provider=provider2, + trigger=Scan.TriggerChoices.MANUAL, + state=StateChoices.COMPLETED, + tenant=tenant, + ) + + ScanSummary.objects.create( + tenant=tenant, + scan=scan1, + check_id="severity-check-one", + service="service-a", + severity="high", + region="region-a", + _pass=4, + fail=4, + muted=0, + total=8, + ) + ScanSummary.objects.create( + tenant=tenant, + scan=scan1, + check_id="severity-check-two", + service="service-a", + severity="medium", + region="region-b", + _pass=2, + fail=2, + muted=0, + total=4, + ) + ScanSummary.objects.create( + tenant=tenant, + scan=scan2, + check_id="severity-check-three", + service="service-b", + severity="critical", + region="region-c", + _pass=1, + fail=2, + muted=0, + total=3, + ) + + single_response = authenticated_client.get( + reverse("overview-findings_severity"), + {"filter[provider_id__in]": str(provider1.id)}, + ) + assert single_response.status_code == status.HTTP_200_OK + single_attributes = single_response.json()["data"]["attributes"] + assert single_attributes["high"] == 8 + assert single_attributes["medium"] == 4 + assert single_attributes["critical"] == 0 + + combined_response = authenticated_client.get( + reverse("overview-findings_severity"), + {"filter[provider_id__in]": f"{provider1.id},{provider2.id}"}, + ) + assert combined_response.status_code == status.HTTP_200_OK + combined_attributes = combined_response.json()["data"]["attributes"] + assert combined_attributes["high"] == 8 + assert combined_attributes["medium"] == 4 + assert combined_attributes["critical"] == 3 + @pytest.mark.django_db class TestScheduleViewSet: diff --git a/docs/docs.json b/docs/docs.json index 69fb3cccde..fb7e91a774 100644 --- a/docs/docs.json +++ b/docs/docs.json @@ -41,13 +41,6 @@ "getting-started/basic-usage/prowler-cli" ] }, - { - "group": "Prowler Lighthouse AI", - "pages": [ - "user-guide/tutorials/prowler-app-lighthouse", - "getting-started/goto/prowler-mcp" - ] - }, { "group": "Prowler App", "pages": [ @@ -56,6 +49,21 @@ "getting-started/basic-usage/prowler-app" ] }, + { + "group": "Prowler Lighthouse AI", + "pages": [ + "user-guide/tutorials/prowler-app-lighthouse" + ] + }, + { + "group": "Prowler MCP Server", + "pages": [ + "getting-started/products/prowler-mcp", + "getting-started/installation/prowler-mcp", + "getting-started/basic-usage/prowler-mcp", + "getting-started/basic-usage/prowler-mcp-tools" + ] + }, { "group": "Prowler Hub", "pages": [ @@ -396,14 +404,6 @@ "source": "/projects/prowler-open-source/en/latest/tutorials/gcp/getting-started-gcp", "destination": "/user-guide/providers/gcp/getting-started-gcp" }, - { - "source": "/projects/prowler-open-source/en/latest/tutorials/prowler-app", - "destination": "/user-guide/tutorials/prowler-app#step-4-4%3A-kubernetes-credentials%3A" - }, - { - "source": "/projects/prowler-open-source/en/latest/tutorials/prowler-app/#step-3-add-a-provider", - "destination": "/user-guide/tutorials/prowler-app#step-3-add-a-provider" - }, { "source": "/projects/prowler-open-source/en/latest/tutorials/microsoft365/getting-started-m365", "destination": "/user-guide/providers/microsoft365/getting-started-m365" @@ -423,6 +423,10 @@ { "source": "/projects/prowler-saas/en/latest/:slug*", "destination": "https://docs.prowler.pro/en/latest/:slug*" + }, + { + "source": "/projects/prowler-open-source/en/latest/tutorials/:slug*", + "destination": "/user-guide/tutorials/:slug*" } ] } diff --git a/docs/getting-started/basic-usage/prowler-mcp-tools.mdx b/docs/getting-started/basic-usage/prowler-mcp-tools.mdx new file mode 100644 index 0000000000..dc984c9537 --- /dev/null +++ b/docs/getting-started/basic-usage/prowler-mcp-tools.mdx @@ -0,0 +1,122 @@ +--- +title: "Tools Reference" +--- + +Complete reference guide for all tools available in the Prowler MCP Server. Tools are organized by namespace. + +## Tool Categories Summary + +| Category | Tool Count | Authentication Required | +|----------|------------|------------------------| +| Prowler Hub | 10 tools | No | +| Prowler Documentation | 2 tools | No | +| Prowler Cloud/App | 28 tools | Yes | + +## Tool Naming Convention + +All tools follow a consistent naming pattern with prefixes: + +- `prowler_hub_*` - Prowler Hub catalog and compliance tools +- `prowler_docs_*` - Prowler documentation search and retrieval +- `prowler_app_*` - Prowler Cloud and App (Self-Managed) management tools + +## Prowler Hub Tools + +Access Prowler's security check catalog and compliance frameworks. **No authentication required.** + +### Check Discovery + +- **`prowler_hub_get_checks`** - List security checks with advanced filtering options +- **`prowler_hub_get_check_filters`** - Return available filter values for checks (providers, services, severities, categories, compliances) +- **`prowler_hub_search_checks`** - Full-text search across check metadata +- **`prowler_hub_get_check_raw_metadata`** - Fetch raw check metadata in JSON format + +### Check Code + +- **`prowler_hub_get_check_code`** - Fetch the Python implementation code for a security check +- **`prowler_hub_get_check_fixer`** - Fetch the automated fixer code for a check (if available) + +### Compliance Frameworks + +- **`prowler_hub_get_compliance_frameworks`** - List and filter compliance frameworks +- **`prowler_hub_search_compliance_frameworks`** - Full-text search across compliance frameworks + +### Provider Information + +- **`prowler_hub_list_providers`** - List Prowler official providers and their services +- **`prowler_hub_get_artifacts_count`** - Get total count of checks and frameworks in Prowler Hub + +## Prowler Documentation Tools + +Search and access official Prowler documentation. **No authentication required.** + +- **`prowler_docs_search`** - Search the official Prowler documentation using full-text search +- **`prowler_docs_get_document`** - Retrieve the full markdown content of a specific documentation file + +## Prowler Cloud/App Tools + +Manage Prowler Cloud or Prowler App (Self-Managed) features. **Requires authentication.** + + +These tools require a valid API key. See the [Configuration Guide](/getting-started/basic-usage/prowler-mcp) for authentication setup. + + +### Findings Management + +- **`prowler_app_list_findings`** - List security findings with advanced filtering +- **`prowler_app_get_finding`** - Get detailed information about a specific finding +- **`prowler_app_get_latest_findings`** - Retrieve latest findings from the most recent scans +- **`prowler_app_get_findings_metadata`** - Get unique metadata values from filtered findings +- **`prowler_app_get_latest_findings_metadata`** - Get metadata from latest findings across all providers + +### Provider Management + +- **`prowler_app_list_providers`** - List all providers with filtering options +- **`prowler_app_create_provider`** - Create a new provider in the current tenant +- **`prowler_app_get_provider`** - Get detailed information about a specific provider +- **`prowler_app_update_provider`** - Update provider details (alias, etc.) +- **`prowler_app_delete_provider`** - Delete a specific provider +- **`prowler_app_test_provider_connection`** - Test provider connection status + +### Provider Secrets Management + +- **`prowler_app_list_provider_secrets`** - List all provider secrets with filtering +- **`prowler_app_add_provider_secret`** - Add or update credentials for a provider +- **`prowler_app_get_provider_secret`** - Get detailed information about a provider secret +- **`prowler_app_update_provider_secret`** - Update provider secret details +- **`prowler_app_delete_provider_secret`** - Delete a provider secret + +### Scan Management + +- **`prowler_app_list_scans`** - List all scans with filtering options +- **`prowler_app_create_scan`** - Trigger a manual scan for a specific provider +- **`prowler_app_get_scan`** - Get detailed information about a specific scan +- **`prowler_app_update_scan`** - Update scan details +- **`prowler_app_get_scan_compliance_report`** - Download compliance report as CSV +- **`prowler_app_get_scan_report`** - Download ZIP file containing complete scan report + +### Schedule Management + +- **`prowler_app_schedules_daily_scan`** - Create a daily scheduled scan for a provider + +### Processor Management + +- **`prowler_app_processors_list`** - List all processors with filtering +- **`prowler_app_processors_create`** - Create a new processor (currently only mute lists supported) +- **`prowler_app_processors_retrieve`** - Get processor details by ID +- **`prowler_app_processors_partial_update`** - Update processor configuration +- **`prowler_app_processors_destroy`** - Delete a processor + +## Usage Tips + +- Use natural language to interact with the tools through your AI assistant +- Tools can be combined for complex workflows +- Filter options are available on most list tools +- Authentication is only required for Prowler Cloud/App tools + +## Additional Resources + +- [MCP Protocol Specification](https://modelcontextprotocol.io) +- [Prowler API Documentation](https://api.prowler.com/api/v1/docs) +- [Prowler Hub API](https://hub.prowler.com/api/docs) +- [GitHub Repository](https://github.com/prowler-cloud/prowler) diff --git a/docs/getting-started/basic-usage/prowler-mcp.mdx b/docs/getting-started/basic-usage/prowler-mcp.mdx new file mode 100644 index 0000000000..90cc3e0e63 --- /dev/null +++ b/docs/getting-started/basic-usage/prowler-mcp.mdx @@ -0,0 +1,247 @@ +--- +title: "Configuration" +--- + +Configure your MCP client to connect to Prowler MCP Server. + +## Step 1: Get Your API Key (Optional) + + +**Authentication is optional**: Prowler Hub and Prowler Documentation features work without authentication. An API key is only required for Prowler Cloud and Prowler App (Self-Managed) features. + + +To use Prowler Cloud or Prowler App (Self-Managed) features. To get the API key, please refer to the [API Keys](/user-guide/providers/prowler-app-api-keys) guide. + + +Keep the API key secure. Never share it publicly or commit it to version control. + + +## Step 2: Configure Your MCP Client + +Choose the configuration based on your deployment: + +- **STDIO Mode**: Local installation only (runs as subprocess). +- **HTTP Mode**: Prowler Cloud MCP Server or self-hosted Prowler MCP Server. + +### HTTP Mode (Prowler Cloud MCP Server or self-hosted Prowler MCP Server) + + + + **Clients that support HTTP with custom headers natively** + + For example: Cursor, VSCode, LobeChat, etc. + + **Configuration:** + ```json + { + "mcpServers": { + "prowler": { + "url": "https://mcp.prowler.com/mcp", // or your self-hosted Prowler MCP Server URL + "headers": { + "Authorization": "Bearer pk_your_api_key_here" + } + } + } + } + ``` + + + + + **For clients without native HTTP support (like Claude Desktop)** + + For example: Claude Desktop. + + **Configuration:** + ```json + { + "mcpServers": { + "prowler": { + "command": "npx", + "args": [ + "mcp-remote", + "https://mcp.prowler.com/mcp", // or your self-hosted Prowler MCP Server URL + "--header", + "Authorization: Bearer ${PROWLER_APP_API_KEY}" + ], + "env": { + "PROWLER_APP_API_KEY": "pk_your_api_key_here" + } + } + } + } + ``` + + + The `mcp-remote` tool acts as a bridge for clients that don't support HTTP natively. Learn more at [mcp-remote on npm](https://www.npmjs.com/package/mcp-remote). + + + + + +### STDIO Mode (Local Installation Only) + +STDIO mode is only available when running the MCP server locally. + + + + **Run from source or local installation** + + ```json + { + "mcpServers": { + "prowler": { + "command": "uvx", + "args": ["/absolute/path/to/prowler/mcp_server/"], + "env": { + "PROWLER_APP_API_KEY": "pk_your_api_key_here", + "PROWLER_API_BASE_URL": "https://api.prowler.com" + } + } + } + } + ``` + + + Replace `/absolute/path/to/prowler/mcp_server/` with the actual path. The `PROWLER_API_BASE_URL` is optional and defaults to Prowler Cloud API. + + + + + + **Run with Docker image** + + ```json + { + "mcpServers": { + "prowler": { + "command": "docker", + "args": [ + "run", + "--rm", + "-i", + "--env", + "PROWLER_APP_API_KEY=pk_your_api_key_here", + "--env", + "PROWLER_API_BASE_URL=https://api.prowler.com", + "prowlercloud/prowler-mcp" + ] + } + } + } + ``` + + + The `PROWLER_API_BASE_URL` is optional and defaults to Prowler Cloud API. + + + + + +## Step 3: Start Using Prowler MCP + +Restart your MCP client and start asking questions: +- *"Show me all critical findings from my AWS accounts"* +- *"What does the S3 bucket public access check do?"* +- *"Onboard this new AWS account in my Prowler Organization"* + +## Authentication Methods + +Prowler MCP Server supports two authentication methods to connect to Prowler Cloud or Prowler App (Self-Managed): + +### API Key (Recommended) + +Use your Prowler API key directly in the Bearer token: + +``` +Authorization: Bearer pk_your_api_key_here +``` + +This is the recommended method for most users. + +### JWT Token + +Alternatively, obtain a JWT token from Prowler: + +```bash +curl -X POST https://api.prowler.com/api/v1/tokens \ + -H "Content-Type: application/vnd.api+json" \ + -H "Accept: application/vnd.api+json" \ + -d '{ + "data": { + "type": "tokens", + "attributes": { + "email": "your-email@example.com", + "password": "your-password" + } + } + }' +``` + +Use the returned JWT token in place of the API key: + +``` +Authorization: Bearer eyJhbGciOiJIUzI1NiIs... +``` + + +JWT tokens are only valid for 30 minutes. You need to generate a new token if you want to continue using the MCP server. + + +## Troubleshooting + +### Server Not Detected + +- Restart your MCP client after configuration changes +- Check the configuration file syntax (valid JSON) +- Review client logs for specific error messages +- Verify the server URL is correct + +### Authentication Failures + +**Error: Unauthorized (401)** +- Verify your API key is correct +- Ensure the key hasn't expired +- Check you're using the right API endpoint + +### Connection Issues + +**Cannot Reach Server:** +- Verify the server URL is correct +- Check network connectivity +- For local servers, ensure the server is running +- Check firewall settings + +## Security Best Practices + +1. **Protect Your API Key** + - Never commit API keys to version control. + - Use environment variables or secure vaults. + - Rotate keys regularly. + +2. **Network Security** + - Use HTTPS for production deployments. + - Restrict network access to the MCP server. + - Consider VPN for remote access. + +3. **Least Privilege** + - API key gives the permission of the user who created the key, make sure to use the key with the minimal required permissions. + - Review the tools that are gonna be used and how they are gonna be used to avoid prompt injections or unintended behavior. + +## Next Steps + +Now that your MCP server is configured: + + + + Explore all available tools + + + +## Getting Help + +Need assistance with configuration? + +- Search for existing [GitHub issues](https://github.com/prowler-cloud/prowler/issues) +- Ask for help in our [Slack community](https://goto.prowler.com/slack) +- Report a new issue on [GitHub](https://github.com/prowler-cloud/prowler/issues/new) diff --git a/docs/getting-started/installation/prowler-mcp.mdx b/docs/getting-started/installation/prowler-mcp.mdx new file mode 100644 index 0000000000..8c3fd2f955 --- /dev/null +++ b/docs/getting-started/installation/prowler-mcp.mdx @@ -0,0 +1,276 @@ +--- +title: "Installation" +--- + +There are **two ways** to use Prowler MCP Server: + + + + **No installation required** - Just configuration + + Use `https://mcp.prowler.com/mcp` + + + **Local installation** - Full control + + Install via Docker, PyPI, or source code + + + + +For "Option 1: Managed by Prowler", go directly to the [Configuration Guide](/getting-started/basic-usage/prowler-mcp#hosted-server-configuration-recommended) to set up your Claude Desktop, Cursor, or other MCP client. +**This guide is focused on local installation, "Option 2: Run Locally"**. + +## Installation Methods + +Choose one of the following installation methods: + + + + ### Pull from Docker Hub + + The easiest way to run locally is using the official Docker image: + + ```bash + docker pull prowlercloud/prowler-mcp + ``` + + ### Run the Container + + ```bash + # STDIO mode (for local MCP clients) + docker run --rm -i prowlercloud/prowler-mcp + + # HTTP mode (for remote access) + docker run --rm -p 8000:8000 \ + prowlercloud/prowler-mcp \ + --transport http --host 0.0.0.0 --port 8000 + ``` + + ### With Environment Variables + + ```bash + docker run --rm -i \ + -e PROWLER_APP_API_KEY="pk_your_api_key" \ + -e PROWLER_API_BASE_URL="https://api.prowler.com" \ + prowlercloud/prowler-mcp + ``` + + + **Docker Hub:** [prowlercloud/prowler-mcp](https://hub.docker.com/r/prowlercloud/prowler-mcp) + + + + + + ### Install via pip + + + **Coming Soon** - PyPI package will be available shortly + + + + + ### Install uv + + If `uv` is not installed, install it first. Visit [uv documentation](https://docs.astral.sh/uv/) for more installation options. + + ### Clone the Repository + + ```bash + git clone https://github.com/prowler-cloud/prowler.git + cd prowler/mcp_server + ``` + + ### Install Dependencies + + The MCP server uses `uv` for dependency management. Install dependencies with: + + ```bash + uv sync + ``` + + ### Verify Installation + + Test that the server is properly installed: + + ```bash + uv run prowler-mcp --help + ``` + + The help message with available command-line options should appear. + + + **For Development:** This method is recommended if you're developing or contributing to the MCP server. + + + + + + ### Prerequisites + + Ensure Docker is installed on your system. Visit [Docker documentation](https://docs.docker.com/get-docker/) for more installation options. + + ### Clone the Repository + + ```bash + git clone https://github.com/prowler-cloud/prowler.git + cd prowler/mcp_server + ``` + + ### Build the Docker Image + + ```bash + docker build -t prowler-mcp . + ``` + + This creates a Docker image named `prowler-mcp` with all necessary dependencies. + + ### Verify Installation + + Test that the Docker image was built successfully: + + ```bash + docker run --rm prowler-mcp --help + ``` + + The help message with available command-line options should appear. + + + + +--- + +## Command Line Options + +The Prowler MCP Server supports the following command-line arguments: + +```bash +prowler-mcp [--transport {stdio,http}] [--host HOST] [--port PORT] +``` + +| Argument | Values | Default | Description | +|----------|--------|---------|-------------| +| `--transport` | `stdio`, `http` | `stdio` | Transport method for MCP communication | +| `--host` | Any valid hostname/IP | `127.0.0.1` | Host to bind to (HTTP mode only) | +| `--port` | Port number | `8000` | Port to bind to (HTTP mode only) | + +### Examples + +```bash +# Default STDIO mode for local MCP client integration +prowler-mcp + +# Explicit STDIO mode +prowler-mcp --transport stdio + +# HTTP mode on default host and port (127.0.0.1:8000) +prowler-mcp --transport http + +# HTTP mode accessible from any network interface +prowler-mcp --transport http --host 0.0.0.0 + +# HTTP mode with custom port +prowler-mcp --transport http --host 0.0.0.0 --port 8080 +``` + +## Environment Variables + +Configure the server using environment variables: + +| Variable | Description | Required | Default | +|----------|-------------|----------|---------| +| `PROWLER_APP_API_KEY` | Prowler API key | Only for STDIO mode | - | +| `PROWLER_API_BASE_URL` | Custom Prowler API endpoint | No | `https://api.prowler.com` | +| `PROWLER_MCP_TRANSPORT_MODE` | Default transport mode (overwritten by `--transport` argument) | No | `stdio` | + + +```bash macOS/Linux +export PROWLER_APP_API_KEY="pk_your_api_key_here" +export PROWLER_API_BASE_URL="https://api.prowler.com" +export PROWLER_MCP_TRANSPORT_MODE="http" +``` + +```bash Windows PowerShell +$env:PROWLER_APP_API_KEY="pk_your_api_key_here" +$env:PROWLER_API_BASE_URL="https://api.prowler.com" +$env:PROWLER_MCP_TRANSPORT_MODE="http" +``` + + + +Never commit your API key to version control. Use environment variables or secure secret management solutions. + + +### Using Environment Files + +For convenience, create a `.env` file in the `mcp_server` directory: + +```bash .env +PROWLER_APP_API_KEY=pk_your_api_key_here +PROWLER_API_BASE_URL=https://api.prowler.com +PROWLER_MCP_TRANSPORT_MODE=stdio +``` + +When using Docker, pass the environment file: + +```bash +docker run --rm --env-file .env -it prowler-mcp +``` + +## Running from Any Location + +Run the MCP server from anywhere using `uvx`: + +```bash +uvx /path/to/prowler/mcp_server/ +``` + +This is particularly useful when configuring MCP clients that need to launch the server from a specific path. + +## Production Deployment + +For production deployments that require customization, it is recommended to use the ASGI application that can be found in `prowler_mcp_server.server`. This can be run with uvicorn: + +```bash +uvicorn prowler_mcp_server.server:app --host 0.0.0.0 --port 8000 +``` + +For more details on production deployment options, see the [FastMCP production deployment guide](https://gofastmcp.com/deployment/http#production-deployment) and [uvicorn settings](https://www.uvicorn.org/settings/). + +### Entrypoint Script + +The source tree includes `entrypoint.sh` to simplify switching between the +standard CLI runner and the ASGI app. The first argument selects the mode and +any additional flags are passed straight through: + +```bash +# Default CLI experience (prowler-mcp console script) +./entrypoint.sh main --transport http --host 0.0.0.0 + +# ASGI app via uvicorn +./entrypoint.sh uvicorn --host 0.0.0.0 --port 9000 +``` + +Omitting the mode defaults to `main`, matching the `prowler-mcp` console script. +When `uvicorn` mode is selected, the script exports `PROWLER_MCP_TRANSPORT_MODE=http` automatically. + +This is the default entrypoint for the Docker container. + +## Next Steps + +Now that you have the Prowler MCP Server installed, proceed to configure your MCP client: + + + + Configure Claude Desktop, Cursor, or other MCP clients + + + +## Getting Help + +If you encounter issues during installation: + +- Search for existing [GitHub issues](https://github.com/prowler-cloud/prowler/issues) +- Ask for help in our [Slack community](https://goto.prowler.com/slack) +- Report a new issue on [GitHub](https://github.com/prowler-cloud/prowler/issues/new) diff --git a/docs/getting-started/products/prowler-mcp.mdx b/docs/getting-started/products/prowler-mcp.mdx new file mode 100644 index 0000000000..cb97efd5ba --- /dev/null +++ b/docs/getting-started/products/prowler-mcp.mdx @@ -0,0 +1,125 @@ +--- +title: "Overview" +--- + +**Prowler MCP Server** brings the entire Prowler ecosystem to AI assistants through the Model Context Protocol (MCP). It enables seamless integration with AI tools like Claude Desktop, Cursor, and other MCP clients, allowing interaction with Prowler's security capabilities through natural language. + + +**Preview Feature**: This MCP server is currently in preview and under active development. Features and functionality may change. We welcome your feedback—please report any issues on [GitHub](https://github.com/prowler-cloud/prowler/issues) or join our [Slack community](https://goto.prowler.com/slack) to discuss and share your thoughts. + + +## What is the Model Context Protocol? + +The [Model Context Protocol (MCP)](https://modelcontextprotocol.io) is an open standard developed by Anthropic that enables AI assistants to securely connect to external data sources and tools. It functions as a universal adapter enabling AI assistants to interact with various services through a standardized interface. + +## Key Capabilities + +The Prowler MCP Server provides three main integration points: + +### 1. Prowler Cloud and Prowler App (Self-Managed) + +Full access to Prowler Cloud platform and self-managed Prowler App for: +- **Provider Management**: Create, configure, and manage cloud providers (AWS, Azure, GCP, etc.). +- **Scan Orchestration**: Trigger on-demand scans and schedule recurring security assessments. +- **Findings Analysis**: Query, filter, and analyze security findings across all your cloud environments. +- **Compliance Reporting**: Generate compliance reports for various frameworks (CIS, PCI-DSS, HIPAA, etc.). +- **Secrets Management**: Securely manage provider credentials and connection details. +- **Processor Configuration**: Set up the [Prowler Mutelist](/user-guide/tutorials/prowler-app-mute-findings) to mute findings. + +### 2. Prowler Hub + +Access to Prowler's comprehensive security knowledge base: +- **Security Checks Catalog**: Browse and search **over 1000 security checks** across multiple cloud providers. +- **Check Implementation**: View the Python code that powers each security check. +- **Automated Fixers**: Access remediation scripts for common security issues. +- **Compliance Frameworks**: Explore mappings to **over 70 compliance standards and frameworks**. +- **Provider Services**: View available services and checks for each cloud provider. + +### 3. Prowler Documentation + +Search and retrieve official Prowler documentation: +- **Intelligent Search**: Full-text search across all Prowler documentation. +- **Contextual Results**: Get relevant documentation pages with highlighted snippets. +- **Document Retrieval**: Access complete markdown content of any documentation file. + +## Use Cases + +The Prowler MCP Server enables powerful workflows through AI assistants: + +**Security Operations** +- "Show me all critical findings from my AWS production accounts" +- "What is my compliance status for the PCI standards accross all my AWS accounts according to the latest Prowler scan results?" +- "Register my new AWS account in Prowler and run an scheduled scan every day" + +**Security Research** +- "Explain what the S3 bucket public access check does" +- "Find all checks related to encryption at rest" +- "What is the latest version of the CIS that Prowler is covering per provider?" + +**Documentation & Learning** +- "How do I configure Prowler to scan my GCP organization?" +- "What authentication methods does Prowler support for Azure?" +- "How can I contribute with a new security check to Prowler?" + +## Deployment Options + +Prowler MCP Server can be used in three ways: + +### 1. Prowler Cloud MCP Server + +**Use Prowler's managed MCP server at `https://mcp.prowler.com/mcp`** + +- No installation required. +- Managed and maintained by Prowler team. +- Authentication to Prowler Cloud or Prowler App (self-managed) via API key or JWT token. + +### 2. Local STDIO Mode + +**Run the server locally on your machine** + +- Runs as a subprocess of your MCP client. +- Possibility to connect to a self-hosted Prowler App (e.g. self-hosted Prowler App). +- Authentication to Prowler Cloud or Prowler App (self-managed) via environment variables. +- Requires Python 3.12+ or Docker. + +### 3. Self-Hosted HTTP Mode + +**Deploy your own remote MCP server** + +- Full control over deployment. +- Possibility to connect to a self-hosted Prowler App (e.g. self-hosted Prowler App). +- Authentication to Prowler App (self-managed) via API key or JWT token. +- Requires Python 3.12+ or Docker. + +## Requirements + +Requirements vary based on deployment option: + +**For Prowler Cloud MCP Server:** +- Prowler Cloud account and API key (only for Prowler Cloud/App features) + +**For self-hosted STDIO/HTTP Mode:** +- Python 3.12+ or Docker +- Network access to: + - `https://hub.prowler.com` (for Prowler Hub) + - `https://docs.prowler.com` (for Prowler Documentation) + - Prowler Cloud API or self-hosted Prowler App API (for Prowler Cloud/App features) + + +**No Authentication Required**: Prowler Hub and Prowler Documentation features work without authentication in both deployment options. A Prowler API key is only required to access Prowler Cloud or Prowler App (Self-Managed) features. + + +## Next Steps + + + + Install the Prowler MCP Server using uv or Docker + + + Configure your MCP client to connect to the server + + + + + Explore all available tools and capabilities + diff --git a/docs/images/providers/certificate-form.png b/docs/images/providers/certificate-form.png new file mode 100644 index 0000000000..b19c079d23 Binary files /dev/null and b/docs/images/providers/certificate-form.png differ diff --git a/docs/images/providers/m365-auth-selection-form.png b/docs/images/providers/m365-auth-selection-form.png new file mode 100644 index 0000000000..4757f44d96 Binary files /dev/null and b/docs/images/providers/m365-auth-selection-form.png differ diff --git a/docs/images/providers/secret-form.png b/docs/images/providers/secret-form.png new file mode 100644 index 0000000000..e202c56aab Binary files /dev/null and b/docs/images/providers/secret-form.png differ diff --git a/docs/introduction.mdx b/docs/introduction.mdx index db37bea7ba..811dc794b7 100644 --- a/docs/introduction.mdx +++ b/docs/introduction.mdx @@ -5,69 +5,47 @@ ![](/images/products/overview.png) - + Command Line Interface - + Web Application - + A managed service built on top of Prowler App. - + A public library of versioned checks, cloud service artifacts, and compliance frameworks. ## Supported Providers + The supported providers right now are: -| Provider | Support | Interface | -|----------|--------|----------| -| [AWS](/user-guide/providers/aws/getting-started-aws) | Official | UI, API, CLI | -| [Azure](/user-guide/providers/azure/getting-started-azure) | Official | UI, API, CLI | -| [Google Cloud](/user-guide/providers/gcp/getting-started-gcp) | Official | UI, API, CLI | -| [Kubernetes](/user-guide/providers/kubernetes/in-cluster) | Official | UI, API, CLI | -| [M365](/user-guide/providers/microsoft365/getting-started-m365) | Official | UI, API, CLI | -| [Github](/user-guide/providers/github/getting-started-github) | Official | UI, API, CLI | -| [Oracle Cloud](/user-guide/providers/oci/getting-started-oci) | Official | CLI | -| [Infra as Code](/user-guide/providers/iac/getting-started-iac) | Official | CLI | -| [MongoDB Atlas](/user-guide/providers/mongodbatlas/getting-started-mongodbatlas) | Official | CLI | -| [LLM](/user-guide/providers/llm/getting-started-llm) | Official | CLI | -| **NHN** | Unofficial | CLI | +| Provider | Support | Interface | +| -------------------------------------------------------------------------------- | ---------- | ------------ | +| [AWS](/user-guide/providers/aws/getting-started-aws) | Official | UI, API, CLI | +| [Azure](/user-guide/providers/azure/getting-started-azure) | Official | UI, API, CLI | +| [Google Cloud](/user-guide/providers/gcp/getting-started-gcp) | Official | UI, API, CLI | +| [Kubernetes](/user-guide/providers/kubernetes/in-cluster) | Official | UI, API, CLI | +| [M365](/user-guide/providers/microsoft365/getting-started-m365) | Official | UI, API, CLI | +| [Github](/user-guide/providers/github/getting-started-github) | Official | UI, API, CLI | +| [Oracle Cloud](/user-guide/providers/oci/getting-started-oci) | Official | CLI | +| [Infra as Code](/user-guide/providers/iac/getting-started-iac) | Official | CLI | +| [MongoDB Atlas](/user-guide/providers/mongodbatlas/getting-started-mongodbatlas) | Official | CLI | +| [LLM](/user-guide/providers/llm/getting-started-llm) | Official | CLI | +| **NHN** | Unofficial | CLI | For more information about the checks and compliance of each provider visit [Prowler Hub](https://hub.prowler.com). ## Where to go next? + - + Detailed instructions on how to use Prowler. - + Interested in contributing to Prowler? - + \ No newline at end of file diff --git a/docs/security.mdx b/docs/security.mdx index 49fb3684bb..d8a3f63c73 100644 --- a/docs/security.mdx +++ b/docs/security.mdx @@ -16,7 +16,7 @@ We use encryption everywhere possible. The data and communications used by **Pro Prowler Cloud is GDPR compliant in regards to personal data and the ["right to be forgotten"](https://gdpr.eu/right-to-be-forgotten/). When a user deletes their account their user information will be deleted from Prowler Cloud online and backup systems within 10 calendar days. -## Software Security +## Software Security We follow a **security-by-design approach** throughout our software development lifecycle. All changes go through automated checks at every stage, from local development to production deployment. diff --git a/docs/user-guide/providers/github/authentication.mdx b/docs/user-guide/providers/github/authentication.mdx index 597a90d658..d76a0a1cb5 100644 --- a/docs/user-guide/providers/github/authentication.mdx +++ b/docs/user-guide/providers/github/authentication.mdx @@ -144,10 +144,19 @@ GitHub Apps provide the recommended integration method for accessing multiple re 2. **Create New GitHub App** - Click "New GitHub App" - Complete the required fields: - - **GitHub App name**: Unique application name - - **Homepage URL**: Application homepage - - **Webhook URL**: Webhook payload URL (optional) - - **Permissions**: Application permission requirements + - **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) + + + **About Homepage URL and Webhooks** + + 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`. + + 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. + 3. **Configure Permissions** To enable Prowler functionality, configure these permissions: diff --git a/docs/user-guide/providers/microsoft365/authentication.mdx b/docs/user-guide/providers/microsoft365/authentication.mdx index 203fcc8e6a..a569008d52 100644 --- a/docs/user-guide/providers/microsoft365/authentication.mdx +++ b/docs/user-guide/providers/microsoft365/authentication.mdx @@ -1,24 +1,26 @@ --- -title: 'Microsoft 365 Authentication in Prowler' +title: "Microsoft 365 Authentication in Prowler" --- Prowler for Microsoft 365 supports multiple authentication types. Authentication methods vary between Prowler App and Prowler CLI: **Prowler App:** -- [**Service Principal Application**](#service-principal-authentication-recommended) (**Recommended**) -- **Service Principal with User Credentials** (Deprecated) +- [**Application Certificate Authentication**](#certificate-based-authentication) (**Recommended**) +- [**Application Client Secret Authentication**](#client-secret-authentication) **Prowler CLI:** -- [**Service Principal Application**](#service-principal-authentication-recommended) (**Recommended**) -- **Service Principal with User Credentials** (Deprecated) -- [**Interactive browser authentication**](#interactive-browser-authentication) +- [**Application Certificate Authentication**](#certificate-based-authentication) (**Recommended**) +- [**Application Client Secret Authentication**](#client-secret-authentication) +- [**Azure CLI Authentication**](#azure-cli-authentication) +- [**Interactive Browser Authentication**](#interactive-browser-authentication) + ## Required Permissions To run the full Prowler provider, including PowerShell checks, two types of permission scopes must be set in **Microsoft Entra ID**. -### Service Principal Authentication Permissions (Recommended) +### Application Permissions for App-Only Authentication When using service principal authentication, add these **Application Permissions**: @@ -35,11 +37,11 @@ When using service principal authentication, add these **Application Permissions - `application_access` from external API `Skype and Teams Tenant Admin API`: Required for Teams PowerShell module app authentication. -`Directory.Read.All` can be replaced with `Domain.Read.All` for more restrictive permissions, but Entra checks related to DirectoryRoles and GetUsers will not run. If using this option, you must also add the `Organization.Read.All` permission to the service principal application for authentication. +`Directory.Read.All` can be replaced with `Domain.Read.All` for more restrictive permissions, but Entra checks related to DirectoryRoles and GetUsers will not run. If using this option, you must also add the `Organization.Read.All` permission to the application registration for authentication. -This is the **recommended authentication method** because it allows running the full M365 provider including PowerShell checks, providing complete coverage of all available security checks. +These permissions enable application-based authentication methods (client secret and certificate). Using certificate-based authentication is the recommended way to run the full M365 provider, including PowerShell checks. ### Browser Authentication Permissions @@ -47,96 +49,189 @@ This is the **recommended authentication method** because it allows running the When using browser authentication, permissions are delegated to the user, so the user must have the appropriate permissions rather than the application. -With browser authentication, you will only be able to run checks that work through MS Graph API. PowerShell module checks will not be executed. +Browser and Azure CLI authentication methods limit scanning capabilities to checks that operate through Microsoft Graph API. Checks requiring PowerShell modules will not execute, as they need application-level permissions that cannot be delegated through browser authentication. ### Step-by-Step Permission Assignment -#### Create Service Principal Application +#### Create Application Registration 1. Access **Microsoft Entra ID** - ![Overview of Microsoft Entra ID](/images/providers/microsoft-entra-id.png) + ![Overview of Microsoft Entra ID](/images/providers/microsoft-entra-id.png) 2. Navigate to "Applications" > "App registrations" - ![App Registration nav](/images/providers/app-registration-menu.png) + ![App Registration nav](/images/providers/app-registration-menu.png) 3. Click "+ New registration", complete the form, and click "Register" - ![New Registration](/images/providers/new-registration.png) + ![New Registration](/images/providers/new-registration.png) 4. Go to "Certificates & secrets" > "Client secrets" > "+ New client secret" - ![Certificate & Secrets nav](/images/providers/certificates-and-secrets.png) + ![Certificate & Secrets nav](/images/providers/certificates-and-secrets.png) 5. Fill in the required fields and click "Add", then copy the generated value (this will be `AZURE_CLIENT_SECRET`) - ![New Client Secret](/images/providers/new-client-secret.png) + ![New Client Secret](/images/providers/new-client-secret.png) #### Grant Microsoft Graph API Permissions 1. Go to App Registration > Select your Prowler App > click on "API permissions" - ![API Permission Page](/images/providers/api-permissions-page.png) + ![API Permission Page](/images/providers/api-permissions-page.png) 2. Click "+ Add a permission" > "Microsoft Graph" > "Application permissions" - ![Add API Permission](/images/providers/add-app-api-permission.png) + ![Add API Permission](/images/providers/add-app-api-permission.png) 3. Search and select the required permissions: - - `AuditLog.Read.All`: Required for Entra service - - `Directory.Read.All`: Required for all services - - `Policy.Read.All`: Required for all services - - `SharePointTenantSettings.Read.All`: Required for SharePoint service - ![Permission Screenshots](/images/providers/directory-permission.png) + - `AuditLog.Read.All`: Required for Entra service + - `Directory.Read.All`: Required for all services + - `Policy.Read.All`: Required for all services + - `SharePointTenantSettings.Read.All`: Required for SharePoint service - ![Application Permissions](/images/providers/app-permissions.png) + ![Permission Screenshots](/images/providers/directory-permission.png) -4. Click "Add permissions", then click "Grant admin consent for ````" + ![Application Permissions](/images/providers/app-permissions.png) -#### Grant PowerShell Module Permissions (For Service Principal Authentication) +4. Click "Add permissions", then click "Grant admin consent for ``" +#### Grant PowerShell Module Permissions 1. **Add Exchange API:** - - Search and select "Office 365 Exchange Online" API in **APIs my organization uses** + - Search and select "Office 365 Exchange Online" API in **APIs my organization uses** - ![Office 365 Exchange Online API](/images/providers/search-exchange-api.png) + ![Office 365 Exchange Online API](/images/providers/search-exchange-api.png) - - Select "Exchange.ManageAsApp" permission and click "Add permissions" + - Select "Exchange.ManageAsApp" permission and click "Add permissions" - ![Exchange.ManageAsApp Permission](/images/providers/exchange-permission.png) + ![Exchange.ManageAsApp Permission](/images/providers/exchange-permission.png) - - Assign `Global Reader` role to the app: Go to `Roles and administrators` > click `here` for directory level assignment + - Assign `Global Reader` role to the app: Go to `Roles and administrators` > click `here` for directory level assignment - ![Roles and administrators](/images/providers/here.png) + ![Roles and administrators](/images/providers/here.png) - - Search for `Global Reader` and assign it to your application + - Search for `Global Reader` and assign it to your application - ![Global Reader Role](/images/providers/global-reader-role.png) + ![Global Reader Role](/images/providers/global-reader-role.png) 2. **Add Teams API:** - - Search and select "Skype and Teams Tenant Admin API" in **APIs my organization uses** + - Search and select "Skype and Teams Tenant Admin API" in **APIs my organization uses** - ![Skype and Teams Tenant Admin API](/images/providers/search-skype-teams-tenant-admin-api.png) + ![Skype and Teams Tenant Admin API](/images/providers/search-skype-teams-tenant-admin-api.png) - - Select "application_access" permission and click "Add permissions" + - Select "application_access" permission and click "Add permissions" - ![application_access Permission](/images/providers/teams-permission.png) + ![application_access Permission](/images/providers/teams-permission.png) 3. Click "Grant admin consent for ``" to grant admin consent - ![Grant Admin Consent](/images/providers/grant-external-api-permissions.png) + ![Grant Admin Consent](/images/providers/grant-external-api-permissions.png) -## Service Principal Authentication (Recommended) +Final permissions should look like this: -*Available for both Prowler App and Prowler CLI* +![Final Permissions](/images/providers/final-permissions.png) + + + +## Application Certificate Authentication (Recommended) + +_Available for both Prowler App and Prowler CLI_ + +**Authentication flag for CLI:** `--certificate-auth` + +Certificate-based authentication replaces the client secret with an X.509 certificate that signs Microsoft Entra ID tokens for the Prowler application registration. + +This is the recommended approach for production environments because it avoids long-lived secrets, supports the full provider (including PowerShell checks), and simplifies unattended automation. Microsoft also recommends certificate credentials for app-only access, see [Manage certificates for applications](https://learn.microsoft.com/en-us/entra/identity-platform/certificate-credentials). + + +### Generate the Certificate + +The service principal needs a certificate that contains the private key locally (for Prowler) and the public key uploaded to Microsoft Entra ID. The following commands show a secure baseline workflow on macOS or Linux using OpenSSL: + +```console +# 1. Create a private key (keep this file private; do not upload it to the portal) +openssl genrsa -out prowlerm365.key 2048 + +# 2. Create a self-signed certificate valid for two years +openssl req -x509 -new -nodes -key prowlerm365.key -sha256 -days 730 -out prowlerm365.cer -subj "/CN=ProwlerM365Cert" + +# 3. Package the key and certificate into a passwordless PFX bundle for Prowler +openssl pkcs12 -export \ + -out prowlerm365.pfx \ + -inkey prowlerm365.key \ + -in prowlerm365.cer \ + -passout pass: +``` + + +Guard `prowlerm365.key` and `prowlerm365.pfx`. Only upload the `.cer` file to the Entra ID portal. Rotate or revoke the certificate before it expires or if there is any suspicion of exposure. + + + +If your organization uses a certificate authority, you can replace step 2 with a CSR workflow and import the signed certificate instead. + +### Upload the Certificate to Microsoft Entra ID + +1. Open **Microsoft Entra ID** > **App registrations** > your application. +2. Go to **Certificates & secrets** > **Certificates**. +3. Select **Upload certificate** and choose `prowlerm365.cer`. +4. Confirm the certificate appears with the expected expiration date. + +After the certificate is in place, encode the PFX file so it can be stored in an environment variable (macOS/Linux example): + +```console +base64 -i prowlerm365.pfx -o prowlerm365.pfx.b64 +cat prowlerm365.pfx.b64 | tr -d '\n' +``` + +Copy the resulting single-line Base64 string (or the contents of `prowlerm365.pfx.b64`)—you will use it in the next step. + +### Provide the Certificate to Prowler + +You can supply the private certificate to Prowler in two ways: + +- **Environment variables (recommended for headless execution)** + + ```console + export AZURE_CLIENT_ID="00000000-0000-0000-0000-000000000000" + export AZURE_TENANT_ID="11111111-1111-1111-1111-111111111111" + export M365_CERTIFICATE_CONTENT="$(base64 < prowlerm365.pfx | tr -d '\n')" + ``` + + The `M365_CERTIFICATE_CONTENT` variable must contain a single-line Base64 string. Remove any line breaks or spaces before exporting. + +- **Local file path** + + Store the PFX securely and reference it when you run the CLI: + + ```console + python3 prowler-cli.py m365 --certificate-auth --certificate-path /secure/path/prowlerm365.pfx + ``` + + The CLI still needs `AZURE_CLIENT_ID` and `AZURE_TENANT_ID` in the environment when you use `--certificate-path`. + +For the **Prowler App**, paste the Base64-encoded PFX in the `certificate_content` field when you configure the provider secrets. The platform persists the encrypted certificate and supplies it during scans. + + +Do not mix certificate authentication with a client secret. Provide either a certificate **or** a secret to the application registration and Prowler configuration. + + + + + + +## Application Client Secret Authentication + +_Available for both Prowler App and Prowler CLI_ **Authentication flag for CLI:** `--sp-env-auth` -Authenticate using the **Service Principal Application** by configuring the following environment variables: +Authenticate using a **Microsoft Entra application registration with a client secret** by configuring the following environment variables: ```console export AZURE_CLIENT_ID="XXXXXXXXX" @@ -150,13 +245,61 @@ Refer to the [Step-by-Step Permission Assignment](#step-by-step-permission-assig If the external API permissions described in the mentioned section above are not added only checks that work through MS Graph will be executed. This means that the full provider will not be executed. +This workflow is helpful for initial validation or temporary access. Plan to transition to certificate-based authentication to remove long-lived secrets and keep full provider coverage in unattended environments. + -In order to scan all the checks from M365 required permissions to the service principal application must be added. Refer to the [PowerShell Module Permissions](#grant-powershell-module-permissions-for-service-principal-authentication) section for more information. +To scan every M365 check, ensure the required permissions are added to the application registration. Refer to the [PowerShell Module Permissions](#grant-powershell-module-permissions-for-app-only-authentication) section for more information. + +### Run Prowler with Certificate Authentication + +After the variables or path are in place, run the Microsoft 365 provider as usual: + +```console +python3 prowler-cli.py m365 --certificate-auth --init-modules --log-level ERROR +``` + +The command above initializes PowerShell modules if needed. You can combine other standard flags (for example, `--region M365USGovernment` or custom outputs) with `--certificate-auth`. + +Prowler prints the certificate thumbprint during execution so you can confirm the correct credential is in use. + + +## Azure CLI Authentication + +_Available only for Prowler CLI_ + +**Authentication flag for CLI:** `--az-cli-auth` + +Azure CLI authentication relies on the identity that is already signed in with the Azure CLI. Before running Prowler, make sure you have an active CLI session in the target tenant: + +```console +az login --tenant +# Optional: enforce the tenant when several are available +az account set --tenant +``` + +If you prefer to reuse the same service principal that powers certificate-based authentication, authenticate it through Azure CLI instead of exporting environment variables. Azure CLI expects the certificate in PEM format; convert the PFX produced earlier and sign in: + +```console +openssl pkcs12 -in prowlerm365.pfx -out prowlerm365.pem -nodes +az login --service-principal \ + --username \ + --password /secure/path/prowlerm365.pem \ + --tenant +``` + +After the CLI session is authenticated, launch Prowler with the Azure CLI flag: + +```console +python3 prowler-cli.py m365 --az-cli-auth +``` + +The Azure CLI identity must hold the same Microsoft Graph and external API permissions required for the full provider. Signing in with a user account limits the scan to delegated Microsoft Graph endpoints and skips PowerShell-based checks. Use a service principal with the necessary application permissions to keep complete coverage. + ## Interactive Browser Authentication -*Available only for Prowler CLI* +_Available only for Prowler CLI_ **Authentication flag:** `--browser-auth` @@ -171,6 +314,7 @@ Since this is a **delegated permission** authentication method, necessary permis PowerShell is required to run certain M365 checks. **Supported versions:** + - **PowerShell 7.4 or higher** (7.5 is recommended) #### Why Is PowerShell 7.4+ Required? @@ -193,6 +337,7 @@ Installing PowerShell is different depending on your OS: ```console winget install --id Microsoft.PowerShell --source winget ``` + [MacOS](https://learn.microsoft.com/es-es/powershell/scripting/install/installing-powershell-on-macos?view=powershell-7.5#install-the-latest-stable-release-of-powershell): installing PowerShell on MacOS needs to have installed [brew](https://brew.sh/), once installed, simply run the command shown above, Pwsh is only supported in macOS 15 (Sequoia) x64 and Arm64, macOS 14 (Sonoma) x64 and Arm64, macOS 13 (Ventura) x64 and Arm64 @@ -202,6 +347,7 @@ Installing PowerShell is different depending on your OS: ``` Once it's installed run `pwsh` on your terminal to verify it's working. + [Ubuntu](https://learn.microsoft.com/es-es/powershell/scripting/install/install-ubuntu?view=powershell-7.5#installation-via-package-repository-the-package-repository): The required version for installing PowerShell +7.4 on Ubuntu are Ubuntu 22.04 and Ubuntu 24.04. @@ -241,6 +387,7 @@ Installing PowerShell is different depending on your OS: # Start PowerShell pwsh ``` + [Alpine](https://learn.microsoft.com/es-es/powershell/scripting/install/install-alpine?view=powershell-7.5#installation-steps): The only supported version for installing PowerShell +7.4 on Alpine is Alpine 3.20. The unique way to install it is downloading the tar.gz package available on [PowerShell github](https://github.com/PowerShell/PowerShell/releases/download/v7.5.0/powershell-7.5.0-linux-musl-x64.tar.gz). @@ -286,6 +433,7 @@ Installing PowerShell is different depending on your OS: # Start PowerShell pwsh ``` + [Debian](https://learn.microsoft.com/es-es/powershell/scripting/install/install-debian?view=powershell-7.5#installation-on-debian-11-or-12-via-the-package-repository): The required version for installing PowerShell +7.4 on Debian are Debian 11 and Debian 12. The recommended way to install it is downloading the package available on PMC. @@ -324,6 +472,7 @@ Installing PowerShell is different depending on your OS: # Start PowerShell pwsh ``` + [Rhel](https://learn.microsoft.com/es-es/powershell/scripting/install/install-rhel?view=powershell-7.5#installation-via-the-package-repository): The required version for installing PowerShell +7.4 on Red Hat are RHEL 8 and RHEL 9. The recommended way to install it is downloading the package available on PMC. @@ -357,6 +506,7 @@ Installing PowerShell is different depending on your OS: # Install PowerShell sudo dnf install powershell -y ``` + [Docker](https://learn.microsoft.com/es-es/powershell/scripting/install/powershell-in-docker?view=powershell-7.5#use-powershell-in-a-container): The following command download the latest stable versions of PowerShell: @@ -370,6 +520,7 @@ Installing PowerShell is different depending on your OS: ```console docker run -it mcr.microsoft.com/dotnet/sdk:9.0 pwsh ``` + ### Required PowerShell Modules @@ -386,6 +537,7 @@ Example command: ```console python3 prowler-cli.py m365 --verbose --log-level ERROR --sp-env-auth --init-modules ``` + If the modules are already installed, running this command will not cause issues—it will simply verify that the necessary modules are available. @@ -399,7 +551,6 @@ Install-Module -Name "ModuleName" -Scope AllUsers -Force #### Modules Version +- [MSAL.PS](https://www.powershellgallery.com/packages/MSAL.PS/4.32.0): Required for Exchange module via application authentication. - [ExchangeOnlineManagement](https://www.powershellgallery.com/packages/ExchangeOnlineManagement/3.6.0) (Minimum version: 3.6.0) Required for checks across Exchange, Defender, and Purview. - [MicrosoftTeams](https://www.powershellgallery.com/packages/MicrosoftTeams/6.6.0) (Minimum version: 6.6.0) Required for all Teams checks. -- [MSAL.PS](https://www.powershellgallery.com/packages/MSAL.PS/4.32.0): Required for Exchange module via application authentication. -- [MSAL.PS](https://www.powershellgallery.com/packages/MSAL.PS/4.32.0): Required for Exchange module via application authentication. diff --git a/docs/user-guide/providers/microsoft365/getting-started-m365.mdx b/docs/user-guide/providers/microsoft365/getting-started-m365.mdx index 67d57911b7..19844b9347 100644 --- a/docs/user-guide/providers/microsoft365/getting-started-m365.mdx +++ b/docs/user-guide/providers/microsoft365/getting-started-m365.mdx @@ -12,8 +12,9 @@ Government cloud accounts or tenants (Microsoft 365 Government) are currently un Configure authentication for Microsoft 365 by following the [Microsoft 365 Authentication](/user-guide/providers/microsoft365/authentication) guide. This includes: -- Creating a Service Principal Application -- Granting required Microsoft Graph API permissions +- Registering an application in Microsoft Entra ID +- Granting all required Microsoft Graph and external API permissions +- Generating the application certificate (recommended) or client secret - Setting up PowerShell module permissions (for full security coverage) ## Prowler App @@ -47,25 +48,38 @@ Configure authentication for Microsoft 365 by following the [Microsoft 365 Authe ![Add Domain ID](/images/providers/add-domain-id.png) -### Step 3: Add Credentials to Prowler App +### Step 3: Select Authentication Method and Provide Credentials -1. Go to App Registration overview and copy the Client ID and Tenant ID +Prowler App now separates Microsoft 365 authentication into two app-only options. After adding the Domain ID, choose the method that matches your setup: - ![App Overview](/images/providers/app-overview.png) +M365 authentication method selection -2. Go to Prowler App and paste: +#### Application Certificate Authentication (Recommended) - - Client ID - - Tenant ID - - `AZURE_CLIENT_SECRET` from the Service Principal setup +1. Copy the Application (client) ID and Tenant ID from the app registration overview page. +2. Paste both values into the Prowler App form. +3. Upload the PFX bundle or paste the Base64-encoded certificate (`M365_CERTIFICATE_CONTENT`), then click **Test Connection**. - ![Prowler Cloud M365 Credentials](/images/providers/m365-credentials.png) +M365 certificate authentication form -3. Click "Next" +Use this method whenever possible to avoid managing client secrets and to unlock every Microsoft 365 check, including those that require PowerShell modules. + +#### Application Client Secret Authentication + +1. From the app registration, copy the Application (client) ID and Tenant ID. +2. Paste both values plus the client secret into the Prowler App form. +3. Click **Test Connection** to validate the credentials. + +M365 client secret authentication form + + +### Step 4: Launch the Scan + +1. Review the summary, then click **Next**. ![Next Detail](/images/providers/click-next-m365.png) -4. Click "Launch Scan" +2. Click **Launch Scan** to start auditing Microsoft 365. ![Launch Scan M365](/images/providers/launch-scan.png) @@ -83,7 +97,9 @@ PowerShell 7.4+ is required for comprehensive Microsoft 365 security coverage. I Select an authentication method from the [Microsoft 365 Authentication](/user-guide/providers/microsoft365/authentication) guide: -- **Service Principal Application** (recommended): `--sp-env-auth` +- **Application Certificate Authentication** (recommended): `--certificate-auth` +- **Application Client Secret Authentication**: `--sp-env-auth` +- **Azure CLI Authentication**: `--az-cli-auth` - **Interactive Browser Authentication**: `--browser-auth` ### Basic Usage diff --git a/docs/user-guide/tutorials/prowler-app.mdx b/docs/user-guide/tutorials/prowler-app.mdx index 803ca0f2f2..dd2074c3b9 100644 --- a/docs/user-guide/tutorials/prowler-app.mdx +++ b/docs/user-guide/tutorials/prowler-app.mdx @@ -207,17 +207,28 @@ If you are adding an **EKS**, **GKE**, **AKS** or external cluster, follow these 4. Now you can add the modified `kubeconfig` in Prowler Cloud. Then test the connection. ### **Step 4.5: M365 Credentials** -For M365, you must enter your Domain ID and choose the authentication method you want to use: +Enter your Microsoft Entra domain (primary tenant domain) and select how the provider should authenticate. Prowler App guides you through the process: -- Service Principal Authentication (Recommended) +M365 authentication method selection - -User authentication with M365_USER and M365_PASSWORD is deprecated and will be removed. +- **Application Client Secret Authentication**: Client secret-based authentication. +- **Application Certificate Authentication (Recommended)**: Certificate-based authentication. Recommended by Microsoft. - -For full setup instructions and requirements, check the [Microsoft 365 provider requirements](/user-guide/providers/microsoft365/getting-started-m365). +#### Step 4.5.1: Application Client Secret Authentication +1. **Enter your tenant ID**: This is the unique identifier for your Microsoft Entra ID directory. +2. **Enter your application (client) ID**: This is the unique identifier assigned to your app registration in Microsoft Entra ID. +3. **Enter your client secret**: This is the secret key used to authenticate your application. -Prowler Cloud M365 Credentials +M365 client secret authentication form + +For full setup instructions, certificate generation commands, and required permissions, review the [Microsoft 365 provider requirements](/user-guide/providers/microsoft365/getting-started-m365). + +#### Step 4.5.2: Application Certificate Authentication (Recommended) +1. **Enter your tenant ID**: This is the unique identifier for your Microsoft Entra ID directory. +2. **Enter your application (client) ID**: This is the unique identifier assigned to your app registration in Microsoft Entra ID. +3. **Upload your certificate file content**: This is the **Base64** encoded certificate content used to authenticate your application. + +M365 certificate authentication form ### **Step 4.6: GitHub Credentials** For GitHub, you must enter your Provider ID (username or organization name) and choose the authentication method you want to use: diff --git a/mcp_server/.env.template b/mcp_server/.env.template index 6227bdd388..7713b5ae33 100644 --- a/mcp_server/.env.template +++ b/mcp_server/.env.template @@ -1,3 +1,3 @@ PROWLER_APP_API_KEY="pk_your_api_key_here" PROWLER_API_BASE_URL="https://api.prowler.com" -PROWLER_MCP_MODE="stdio" +PROWLER_MCP_TRANSPORT_MODE="stdio" diff --git a/mcp_server/CHANGELOG.md b/mcp_server/CHANGELOG.md index be766b4162..490c1878e9 100644 --- a/mcp_server/CHANGELOG.md +++ b/mcp_server/CHANGELOG.md @@ -13,4 +13,5 @@ All notable changes to the **Prowler MCP Server** are documented in this file. - Add new MCP Server for Prowler Documentation [(#8795)](https://github.com/prowler-cloud/prowler/pull/8795) - API key support for STDIO mode and enhanced HTTP mode authentication [(#8823)](https://github.com/prowler-cloud/prowler/pull/8823) - Add health check endpoint [(#8905)](https://github.com/prowler-cloud/prowler/pull/8905) -- Update Prowler Documentation MCP Server to use Mintlify API [(#8915)](https://github.com/prowler-cloud/prowler/pull/8915) +- Update Prowler Documentation MCP Server to use Mintlify API [(#8916)](https://github.com/prowler-cloud/prowler/pull/8916) +- Add custom production deployment using uvicorn [(#8958)](https://github.com/prowler-cloud/prowler/pull/8958) diff --git a/mcp_server/Dockerfile b/mcp_server/Dockerfile index fd92db7cdd..d075e83b5f 100644 --- a/mcp_server/Dockerfile +++ b/mcp_server/Dockerfile @@ -47,13 +47,12 @@ COPY --from=builder --chown=prowler /app/prowler_mcp_server /app/prowler_mcp_ser # 3. Project metadata file (may be needed by some packages at runtime) COPY --from=builder --chown=prowler /app/pyproject.toml /app/pyproject.toml +# 4. Entrypoint helper script for selecting runtime mode +COPY --from=builder --chown=prowler /app/entrypoint.sh /app/entrypoint.sh + # Add virtual environment to PATH so prowler-mcp command is available ENV PATH="/app/.venv/bin:$PATH" -# Entry point for the MCP server -# Default to stdio mode, but allow overriding via command arguments -# Examples: -# docker run -p 8000:8000 prowler-mcp --transport http --host 0.0.0.0 --port 8000 -# docker run prowler-mcp --transport stdio -ENTRYPOINT ["prowler-mcp"] -CMD ["--transport", "stdio"] +# Entrypoint wrapper defaults to CLI mode; override with `uvicorn` to run ASGI app +ENTRYPOINT ["/app/entrypoint.sh"] +CMD ["main"] diff --git a/mcp_server/README.md b/mcp_server/README.md index 25e89568b8..e652ee5fcc 100644 --- a/mcp_server/README.md +++ b/mcp_server/README.md @@ -8,39 +8,108 @@ Access the entire Prowler ecosystem through the Model Context Protocol (MCP). Th - **Prowler Hub**: Access to Prowler's security checks, fixers, and compliance frameworks catalog - **Prowler Documentation**: Search and retrieve official Prowler documentation +## Quick Start with Hosted Server (Recommended) -## Requirements +**The easiest way to use Prowler MCP is through our hosted server at `https://mcp.prowler.com/mcp`** -- Python 3.12+ -- Network access to `https://hub.prowler.com` (for Prowler Hub) -- Network access to `https://prowler.mintlify.app` (for Prowler Documentation) -- Network access to Prowler Cloud and Prowler App (Self-Managed) API (it can be Prowler Cloud API or self-hosted Prowler App API) -- Prowler Cloud account credentials (for Prowler Cloud and Prowler App (Self-Managed) features) +No installation required! Just configure your MCP client: -## Installation - -### From Sources - -It is needed to have [uv](https://docs.astral.sh/uv/) installed. - -```bash -git clone https://github.com/prowler-cloud/prowler.git +```json +{ + "mcpServers": { + "prowler": { + "command": "npx", + "args": [ + "mcp-remote", + "https://mcp.prowler.com/mcp", + "--header", + "Authorization: Bearer pk_YOUR_API_KEY_HERE" + ] + } + } +} ``` -### Using Docker +**Configuration file locations:** +- **Claude Desktop (macOS)**: `~/Library/Application Support/Claude/claude_desktop_config.json` +- **Claude Desktop (Windows)**: `%AppData%\Claude\claude_desktop_config.json` +- **Cursor**: `~/.cursor/mcp.json` -Alternatively, you can build and run the MCP server using Docker: +Get your API key at [Prowler Cloud](https://cloud.prowler.com) → Settings → API Keys + +> **Benefits:** Always up-to-date, no maintenance, managed by Prowler team + +## Local/Self-Hosted Installation + +If you need to run the MCP server locally or self-host it, choose one of the following installation methods. **Configuration is the same** for both managed and local installations - just point to your local server URL instead of `https://mcp.prowler.com/mcp`. + +### Requirements + +- Python 3.12+ (for source/PyPI installation) +- Docker (for Docker installation) +- Network access to `https://hub.prowler.com` (for Prowler Hub) +- Network access to `https://prowler.mintlify.app` (for Prowler Documentation) +- Network access to Prowler Cloud and Prowler App (Self-Managed) API (optional, only for Prowler Cloud/App features) +- Prowler Cloud account credentials (only for Prowler Cloud and Prowler App features) + +### Installation Methods + +#### Option 1: Docker Hub (Recommended) + +Pull the official image from Docker Hub: + +```bash +docker pull prowlercloud/prowler-mcp +``` + +Run in STDIO mode: +```bash +docker run --rm -i prowlercloud/prowler-mcp +``` + +Run in HTTP mode: +```bash +docker run --rm -p 8000:8000 \ + prowlercloud/prowler-mcp \ + --transport http --host 0.0.0.0 --port 8000 +``` + +With environment variables: +```bash +docker run --rm -i \ + -e PROWLER_APP_API_KEY="pk_your_api_key" \ + -e PROWLER_API_BASE_URL="https://api.prowler.com" \ + prowlercloud/prowler-mcp +``` + +**Docker Hub:** [prowlercloud/prowler-mcp](https://hub.docker.com/r/prowlercloud/prowler-mcp) + +#### Option 2: PyPI Package (Coming Soon) + +```bash +pip install prowler-mcp-server +prowler-mcp --help +``` + +#### Option 3: From Source (Development) + +Clone the repository and use `uv`: ```bash -# Clone the repository git clone https://github.com/prowler-cloud/prowler.git cd prowler/mcp_server +uv run prowler-mcp --help +``` -# Build the Docker image +Install [uv](https://docs.astral.sh/uv/) first if needed. + +#### Option 4: Build Docker Image from Source + +```bash +git clone https://github.com/prowler-cloud/prowler.git +cd prowler/mcp_server docker build -t prowler-mcp . - -# Run the container with environment variables -docker run --rm --env-file ./.env -it prowler-mcp +docker run --rm -i prowler-mcp ``` ## Running @@ -75,11 +144,11 @@ uv run prowler-mcp --transport http uv run prowler-mcp --transport http --host 0.0.0.0 --port 8080 ``` -For self-deployed MCP remote server, you can use also configure the server to use a custom API base URL with the environment variable `PROWLER_API_BASE_URL`; and the transport mode with the environment variable `PROWLER_MCP_MODE`. +For self-deployed MCP remote server, you can use also configure the server to use a custom API base URL with the environment variable `PROWLER_API_BASE_URL`; and the transport mode with the environment variable `PROWLER_MCP_TRANSPORT_MODE`. ```bash export PROWLER_API_BASE_URL="https://api.prowler.com" -export PROWLER_MCP_MODE="http" +export PROWLER_MCP_TRANSPORT_MODE="http" ``` ### Using uv directly @@ -121,6 +190,16 @@ docker run --rm --env-file ./.env -p 8000:8000 -it prowler-mcp --transport http docker run --rm --env-file ./.env -p 8080:8080 -it prowler-mcp --transport http --host 0.0.0.0 --port 8080 ``` +## Production Deployment + +For production deployments that require customization, it is recommended to use the ASGI application that can be found in `prowler_mcp_server.server`. This can be run with uvicorn: + +```bash +uvicorn prowler_mcp_server.server:app --host 0.0.0.0 --port 8000 +``` + +For more details on production deployment options, see the [FastMCP production deployment guide](https://gofastmcp.com/deployment/http#production-deployment) and [uvicorn settings](https://www.uvicorn.org/settings/). + ## Command Line Arguments The Prowler MCP server supports the following command line arguments: @@ -320,18 +399,60 @@ For local execution, configure your MCP client to launch the server directly. Be For HTTP mode, you can configure your MCP client to connect to a remote Prowler MCP server. -**Important Limitations:** -- HTTP mode support varies by client - some clients may not support HTTP transport yet. -- Some MCP clients like Claude Desktop only support OAuth authentication for HTTP connections, which is not currently supported by our MCP server. +Most MCP clients don't natively support HTTP transport with Bearer token authentication. However, you can use the `mcp-remote` proxy tool to connect any MCP client to remote HTTP servers. -Example configuration for clients that support HTTP transport: +##### Using mcp-remote Proxy (Recommended for Claude Desktop) + +For clients like Claude Desktop that don't support HTTP transport natively, use the `mcp-remote` npm package as a proxy: **Using API Key (Recommended):** ```json { "mcpServers": { "prowler": { - "url": "http://mcp.prowler.com/mcp", // Replace with your own MCP server URL, by default when server is run in local it is http://localhost:8000/mcp + "command": "npx", + "args": [ + "mcp-remote", + "https://mcp.prowler.com/mcp", + "--header", + "Authorization: Bearer pk_your_api_key_here" + ] + } + } +} +``` + +**Using JWT Token:** +```json +{ + "mcpServers": { + "prowler": { + "command": "npx", + "args": [ + "mcp-remote", + "https://mcp.prowler.com/mcp", + "--header", + "Authorization: Bearer " + ] + } + } +} +``` + +> **Note:** Replace `https://mcp.prowler.com/mcp` with your actual MCP server URL (use `http://localhost:8000/mcp` for local deployment). The `mcp-remote` package is automatically installed by `npx` on first use. + +> **Info:** The `mcp-remote` tool acts as a bridge, converting STDIO protocol (used by Claude Desktop) to HTTP requests (used by the remote MCP server). Learn more at [mcp-remote on npm](https://www.npmjs.com/package/mcp-remote). + +##### Direct HTTP Configuration (For Compatible Clients) + +For clients that natively support HTTP transport with Bearer token authentication: + +**Using API Key:** +```json +{ + "mcpServers": { + "prowler": { + "url": "https://mcp.prowler.com/mcp", "headers": { "Authorization": "Bearer pk_your_api_key_here" } @@ -345,7 +466,7 @@ Example configuration for clients that support HTTP transport: { "mcpServers": { "prowler": { - "url": "http://mcp.prowler.com/mcp", // Replace with your own MCP server URL, by default when server is run in local it is http://localhost:8000/mcp + "url": "https://mcp.prowler.com/mcp", "headers": { "Authorization": "Bearer " } @@ -354,6 +475,8 @@ Example configuration for clients that support HTTP transport: } ``` +> **Note:** Replace `mcp.prowler.com` with your actual server hostname and adjust the port if needed (e.g., `http://localhost:8000/mcp` for local deployment). + ### Claude Desktop (macOS/Windows) Add the example server to Claude Desktop's config file, then restart the app. @@ -369,6 +492,10 @@ If you want to have it globally available, add the example server to Cursor's co If you want to have it only for the current project, add the example server to the project's root in a new `.cursor/mcp.json` file. +## Documentation + +For detailed documentation about the Prowler MCP Server, including guides, tutorials, and use cases, visit the [official Prowler documentation](https://docs.prowler.com). + ## License -This project follows the repository’s main license. See the [LICENSE](../LICENSE) file at the repository root. +This project follows the repository's main license. See the [LICENSE](../LICENSE) file at the repository root. diff --git a/mcp_server/entrypoint.sh b/mcp_server/entrypoint.sh new file mode 100755 index 0000000000..7b56e08708 --- /dev/null +++ b/mcp_server/entrypoint.sh @@ -0,0 +1,50 @@ +#!/bin/sh +set -eu + +usage() { + cat <<'EOF' +Usage: ./entrypoint.sh [main|uvicorn] [args...] + +Modes: + main (default) Run prowler-mcp + uvicorn Run uvicorn prowler_mcp_server.server:app + +All additional arguments are forwarded to the selected command. +EOF +} + +mode="main" + +if [ "$#" -gt 0 ]; then + case "$1" in + main|cli) + mode="main" + shift + ;; + uvicorn|asgi) + mode="uvicorn" + shift + ;; + -h|--help) + usage + exit 0 + ;; + *) + mode="main" + ;; + esac +fi + +case "$mode" in + main) + exec prowler-mcp "$@" + ;; + uvicorn) + export PROWLER_MCP_TRANSPORT_MODE="http" + exec uvicorn prowler_mcp_server.server:app "$@" + ;; + *) + usage + exit 1 + ;; +esac diff --git a/mcp_server/prowler_mcp_server/main.py b/mcp_server/prowler_mcp_server/main.py index 272cfa3043..596e1c31b9 100644 --- a/mcp_server/prowler_mcp_server/main.py +++ b/mcp_server/prowler_mcp_server/main.py @@ -1,10 +1,8 @@ import argparse -import asyncio import os import sys from prowler_mcp_server.lib.logger import logger -from prowler_mcp_server.server import setup_main_server def parse_arguments(): @@ -13,7 +11,7 @@ def parse_arguments(): parser.add_argument( "--transport", choices=["stdio", "http"], - default=os.getenv("PROWLER_MCP_MODE", "stdio"), + default=None, help="Transport method (default: stdio)", ) parser.add_argument( @@ -35,13 +33,26 @@ def main(): try: args = parse_arguments() - # Set up server with configuration - prowler_mcp_server = asyncio.run(setup_main_server(transport=args.transport)) + print(f"args.transport: {args.transport}") + + if args.transport is None: + args.transport = os.getenv("PROWLER_MCP_TRANSPORT_MODE", "stdio") + else: + os.environ["PROWLER_MCP_TRANSPORT_MODE"] = args.transport + + from prowler_mcp_server.server import prowler_mcp_server if args.transport == "stdio": - prowler_mcp_server.run(transport="stdio") + prowler_mcp_server.run(transport=args.transport, show_banner=False) elif args.transport == "http": - prowler_mcp_server.run(transport="http", host=args.host, port=args.port) + prowler_mcp_server.run( + transport=args.transport, + host=args.host, + port=args.port, + show_banner=False, + ) + else: + logger.error(f"Invalid transport: {args.transport}") except KeyboardInterrupt: logger.info("Shutting down Prowler MCP server...") diff --git a/mcp_server/prowler_mcp_server/prowler_app/utils/auth.py b/mcp_server/prowler_mcp_server/prowler_app/utils/auth.py index 1fdc23d431..b23c58d016 100644 --- a/mcp_server/prowler_mcp_server/prowler_app/utils/auth.py +++ b/mcp_server/prowler_mcp_server/prowler_app/utils/auth.py @@ -14,7 +14,7 @@ class ProwlerAppAuth: def __init__( self, - mode: str = os.getenv("PROWLER_MCP_MODE", "stdio"), + mode: str = os.getenv("PROWLER_MCP_TRANSPORT_MODE", "stdio"), base_url: str = os.getenv("PROWLER_API_BASE_URL", "https://api.prowler.com"), ): self.base_url = base_url.rstrip("/") @@ -33,7 +33,14 @@ class ProwlerAppAuth: raise ValueError("Prowler App API key format is incorrect") def _parse_jwt(self, token: str) -> Optional[Dict]: - """Parse JWT token and return payload, similar to JS parseJwt function.""" + """Parse JWT token and return payload + + Args: + token: JWT token to parse + + Returns: + Parsed JWT payload, or None if parsing fails + """ if not token: return None diff --git a/mcp_server/prowler_mcp_server/server.py b/mcp_server/prowler_mcp_server/server.py index 644135497a..9f36befb73 100644 --- a/mcp_server/prowler_mcp_server/server.py +++ b/mcp_server/prowler_mcp_server/server.py @@ -1,16 +1,16 @@ +import asyncio import os from fastmcp import FastMCP +from prowler_mcp_server import __version__ from prowler_mcp_server.lib.logger import logger from starlette.responses import JSONResponse +prowler_mcp_server = FastMCP("prowler-mcp-server") -async def setup_main_server(transport: str) -> FastMCP: + +async def setup_main_server(): """Set up the main Prowler MCP server with all available integrations.""" - - # Initialize main Prowler MCP server - prowler_mcp_server = FastMCP("prowler-mcp-server") - # Import Prowler Hub tools with prowler_hub_ prefix try: logger.info("Importing Prowler Hub server...") @@ -21,12 +21,10 @@ async def setup_main_server(transport: str) -> FastMCP: except Exception as e: logger.error(f"Failed to import Prowler Hub server: {e}") + # Import Prowler App tools with prowler_app_ prefix try: logger.info("Importing Prowler App server...") - if os.getenv("PROWLER_MCP_MODE", None) is None: - os.environ["PROWLER_MCP_MODE"] = transport - if not os.path.exists( os.path.join(os.path.dirname(__file__), "prowler_app", "server.py") ): @@ -44,6 +42,7 @@ async def setup_main_server(transport: str) -> FastMCP: except Exception as e: logger.error(f"Failed to import Prowler App server: {e}") + # Import Prowler Documentation tools with prowler_docs_ prefix try: logger.info("Importing Prowler Documentation server...") from prowler_mcp_server.prowler_documentation.server import docs_mcp_server @@ -53,9 +52,23 @@ async def setup_main_server(transport: str) -> FastMCP: except Exception as e: logger.error(f"Failed to import Prowler Documentation server: {e}") - # Add health check endpoint - @prowler_mcp_server.custom_route("/health", methods=["GET"]) - async def health_check(request): - return JSONResponse({"status": "healthy", "service": "prowler-mcp-server"}) - return prowler_mcp_server +# Add health check endpoint +@prowler_mcp_server.custom_route("/health", methods=["GET"]) +async def health_check(request) -> JSONResponse: + """Health check endpoint.""" + return JSONResponse( + {"status": "healthy", "service": "prowler-mcp-server", "version": __version__} + ) + + +# Get or create the event loop +try: + loop = asyncio.get_running_loop() + # If we have a running loop, schedule the setup as a task + loop.create_task(setup_main_server()) +except RuntimeError: + # No running loop, use asyncio.run (for standalone execution) + asyncio.run(setup_main_server()) + +app = prowler_mcp_server.http_app() diff --git a/poetry.lock b/poetry.lock index 9451ead963..847a31f878 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 2.2.0 and should not be changed by hand. +# This file is automatically @generated by Poetry 2.1.1 and should not be changed by hand. [[package]] name = "about-time" @@ -834,21 +834,6 @@ typing-extensions = ">=4.6.0" [package.extras] aio = ["azure-core[aio] (>=1.30.0)"] -[[package]] -name = "babel" -version = "2.17.0" -description = "Internationalization utilities" -optional = false -python-versions = ">=3.8" -groups = ["docs"] -files = [ - {file = "babel-2.17.0-py3-none-any.whl", hash = "sha256:4d0b53093fdfb4b21c92b5213dba5a1b23885afa8383709427046b21c366e5f2"}, - {file = "babel-2.17.0.tar.gz", hash = "sha256:0c54cffb19f690cdcc52a3b50bcbf71e07a808d1c80d549f2459b9d2cf0afb9d"}, -] - -[package.extras] -dev = ["backports.zoneinfo ; python_version < \"3.9\"", "freezegun (>=1.0,<2.0)", "jinja2 (>=3.0)", "pytest (>=6.0)", "pytest-cov", "pytz", "setuptools", "tzdata ; sys_platform == \"win32\""] - [[package]] name = "bandit" version = "1.8.3" @@ -994,7 +979,7 @@ version = "2025.7.14" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.7" -groups = ["main", "dev", "docs"] +groups = ["main", "dev"] files = [ {file = "certifi-2025.7.14-py3-none-any.whl", hash = "sha256:6b31f564a415d79ee77df69d757bb49a5bb53bd9f756cbbe24394ffd6fc1f4b2"}, {file = "certifi-2025.7.14.tar.gz", hash = "sha256:8ea99dbdfaaf2ba2f9bac77b9249ef62ec5218e7c2b2e903378ed5fccf765995"}, @@ -1126,7 +1111,7 @@ version = "3.4.2" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." optional = false python-versions = ">=3.7" -groups = ["main", "dev", "docs"] +groups = ["main", "dev"] files = [ {file = "charset_normalizer-3.4.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7c48ed483eb946e6c04ccbe02c6b4d1d48e51944b6db70f697e089c193404941"}, {file = "charset_normalizer-3.4.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b2d318c11350e10662026ad0eb71bb51c7812fc8590825304ae0bdd4ac283acd"}, @@ -1240,7 +1225,7 @@ version = "8.1.8" description = "Composable command line interface toolkit" optional = false python-versions = ">=3.7" -groups = ["main", "dev", "docs"] +groups = ["main", "dev"] markers = "python_version < \"3.10\"" files = [ {file = "click-8.1.8-py3-none-any.whl", hash = "sha256:63c132bbbed01578a06712a2d1f497bb62d9c1c0d329b7903a866228027263b2"}, @@ -1256,7 +1241,7 @@ version = "8.2.1" description = "Composable command line interface toolkit" optional = false python-versions = ">=3.10" -groups = ["main", "dev", "docs"] +groups = ["main", "dev"] markers = "python_version >= \"3.10\"" files = [ {file = "click-8.2.1-py3-none-any.whl", hash = "sha256:61a3265b914e850b85317d0b3109c7f8cd35a670f963866005d6ef1d5175a12b"}, @@ -1290,7 +1275,7 @@ version = "0.4.6" description = "Cross-platform colored terminal text." optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" -groups = ["main", "dev", "docs"] +groups = ["main", "dev"] files = [ {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, @@ -1921,59 +1906,6 @@ files = [ {file = "frozenlist-1.7.0.tar.gz", hash = "sha256:2e310d81923c2437ea8670467121cc3e9b0f76d3043cc1d2331d56c7fb7a3a8f"}, ] -[[package]] -name = "ghp-import" -version = "2.1.0" -description = "Copy your docs directly to the gh-pages branch." -optional = false -python-versions = "*" -groups = ["docs"] -files = [ - {file = "ghp-import-2.1.0.tar.gz", hash = "sha256:9c535c4c61193c2df8871222567d7fd7e5014d835f97dc7b7439069e2413d343"}, - {file = "ghp_import-2.1.0-py3-none-any.whl", hash = "sha256:8337dd7b50877f163d4c0289bc1f1c7f127550241988d568c1db512c4324a619"}, -] - -[package.dependencies] -python-dateutil = ">=2.8.1" - -[package.extras] -dev = ["flake8", "markdown", "twine", "wheel"] - -[[package]] -name = "gitdb" -version = "4.0.12" -description = "Git Object Database" -optional = false -python-versions = ">=3.7" -groups = ["docs"] -files = [ - {file = "gitdb-4.0.12-py3-none-any.whl", hash = "sha256:67073e15955400952c6565cc3e707c554a4eea2e428946f7a4c162fab9bd9bcf"}, - {file = "gitdb-4.0.12.tar.gz", hash = "sha256:5ef71f855d191a3326fcfbc0d5da835f26b13fbcba60c32c21091c349ffdb571"}, -] - -[package.dependencies] -smmap = ">=3.0.1,<6" - -[[package]] -name = "gitpython" -version = "3.1.45" -description = "GitPython is a Python library used to interact with Git repositories" -optional = false -python-versions = ">=3.7" -groups = ["docs"] -files = [ - {file = "gitpython-3.1.45-py3-none-any.whl", hash = "sha256:8908cb2e02fb3b93b7eb0f2827125cb699869470432cc885f019b8fd0fccff77"}, - {file = "gitpython-3.1.45.tar.gz", hash = "sha256:85b0ee964ceddf211c41b9f27a49086010a190fd8132a24e21f362a4b36a791c"}, -] - -[package.dependencies] -gitdb = ">=4.0.1,<5" -typing-extensions = {version = ">=3.10.0.2", markers = "python_version < \"3.10\""} - -[package.extras] -doc = ["sphinx (>=7.1.2,<7.2)", "sphinx-autodoc-typehints", "sphinx_rtd_theme"] -test = ["coverage[toml]", "ddt (>=1.1.1,!=1.4.3)", "mock ; python_version < \"3.8\"", "mypy", "pre-commit", "pytest (>=7.3.1)", "pytest-cov", "pytest-instafail", "pytest-mock", "pytest-sugar", "typing-extensions ; python_version < \"3.11\""] - [[package]] name = "google-api-core" version = "2.25.1" @@ -2258,7 +2190,7 @@ version = "3.10" description = "Internationalized Domain Names in Applications (IDNA)" optional = false python-versions = ">=3.6" -groups = ["main", "dev", "docs"] +groups = ["main", "dev"] files = [ {file = "idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3"}, {file = "idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9"}, @@ -2273,12 +2205,12 @@ version = "8.7.0" description = "Read metadata from Python packages" optional = false python-versions = ">=3.9" -groups = ["main", "dev", "docs"] +groups = ["main", "dev"] files = [ {file = "importlib_metadata-8.7.0-py3-none-any.whl", hash = "sha256:e5dd1551894c77868a30651cef00984d50e1002d06942a7101d34870c5f02afd"}, {file = "importlib_metadata-8.7.0.tar.gz", hash = "sha256:d13b81ad223b890aa16c5471f2ac3056cf76c5f10f82d6f9292f0b415f389000"}, ] -markers = {dev = "python_version < \"3.10\"", docs = "python_version < \"3.10\""} +markers = {dev = "python_version < \"3.10\""} [package.dependencies] zipp = ">=3.20" @@ -2350,7 +2282,7 @@ version = "3.1.6" description = "A very fast and expressive template engine." optional = false python-versions = ">=3.7" -groups = ["main", "dev", "docs"] +groups = ["main", "dev"] files = [ {file = "jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67"}, {file = "jinja2-3.1.6.tar.gz", hash = "sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d"}, @@ -2416,6 +2348,8 @@ python-versions = "*" groups = ["dev"] files = [ {file = "jsonpath-ng-1.7.0.tar.gz", hash = "sha256:f6f5f7fd4e5ff79c785f1573b394043b39849fb2bb47bcead935d12b00beab3c"}, + {file = "jsonpath_ng-1.7.0-py2-none-any.whl", hash = "sha256:898c93fc173f0c336784a3fa63d7434297544b7198124a68f9a3ef9597b0ae6e"}, + {file = "jsonpath_ng-1.7.0-py3-none-any.whl", hash = "sha256:f3d7f9e848cba1b6da28c55b1c26ff915dc9e0b1ba7e752a53d6da8d5cbd00b6"}, ] [package.dependencies] @@ -2546,7 +2480,7 @@ version = "3.9" description = "Python implementation of John Gruber's Markdown." optional = false python-versions = ">=3.9" -groups = ["main", "docs"] +groups = ["main"] files = [ {file = "markdown-3.9-py3-none-any.whl", hash = "sha256:9f4d91ed810864ea88a6f32c07ba8bee1346c0cc1f6b1f9f6c822f2a9667d280"}, {file = "markdown-3.9.tar.gz", hash = "sha256:d2900fe1782bd33bdbbd56859defef70c2e78fc46668f8eb9df3128138f2cb6a"}, @@ -2590,7 +2524,7 @@ version = "3.0.2" description = "Safely add untrusted strings to HTML/XML markup." optional = false python-versions = ">=3.9" -groups = ["main", "dev", "docs"] +groups = ["main", "dev"] files = [ {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7e94c425039cde14257288fd61dcfb01963e658efbc0ff54f5306b06054700f8"}, {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9e2d922824181480953426608b81967de705c3cef4d1af983af849d7bd619158"}, @@ -2699,18 +2633,6 @@ files = [ {file = "mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba"}, ] -[[package]] -name = "mergedeep" -version = "1.3.4" -description = "A deep merge function for 🐍." -optional = false -python-versions = ">=3.6" -groups = ["docs"] -files = [ - {file = "mergedeep-1.3.4-py3-none-any.whl", hash = "sha256:70775750742b25c0d8f36c55aed03d24c3384d17c951b3175d898bd778ef0307"}, - {file = "mergedeep-1.3.4.tar.gz", hash = "sha256:0096d52e9dad9939c3d975a774666af186eda617e6ca84df4c94dec30004f2a8"}, -] - [[package]] name = "microsoft-kiota-abstractions" version = "1.9.2" @@ -2825,116 +2747,6 @@ files = [ [package.dependencies] microsoft-kiota-abstractions = ">=1.9.2,<1.10.0" -[[package]] -name = "mkdocs" -version = "1.6.1" -description = "Project documentation with Markdown." -optional = false -python-versions = ">=3.8" -groups = ["docs"] -files = [ - {file = "mkdocs-1.6.1-py3-none-any.whl", hash = "sha256:db91759624d1647f3f34aa0c3f327dd2601beae39a366d6e064c03468d35c20e"}, - {file = "mkdocs-1.6.1.tar.gz", hash = "sha256:7b432f01d928c084353ab39c57282f29f92136665bdd6abf7c1ec8d822ef86f2"}, -] - -[package.dependencies] -click = ">=7.0" -colorama = {version = ">=0.4", markers = "platform_system == \"Windows\""} -ghp-import = ">=1.0" -importlib-metadata = {version = ">=4.4", markers = "python_version < \"3.10\""} -jinja2 = ">=2.11.1" -markdown = ">=3.3.6" -markupsafe = ">=2.0.1" -mergedeep = ">=1.3.4" -mkdocs-get-deps = ">=0.2.0" -packaging = ">=20.5" -pathspec = ">=0.11.1" -pyyaml = ">=5.1" -pyyaml-env-tag = ">=0.1" -watchdog = ">=2.0" - -[package.extras] -i18n = ["babel (>=2.9.0)"] -min-versions = ["babel (==2.9.0)", "click (==7.0)", "colorama (==0.4) ; platform_system == \"Windows\"", "ghp-import (==1.0)", "importlib-metadata (==4.4) ; python_version < \"3.10\"", "jinja2 (==2.11.1)", "markdown (==3.3.6)", "markupsafe (==2.0.1)", "mergedeep (==1.3.4)", "mkdocs-get-deps (==0.2.0)", "packaging (==20.5)", "pathspec (==0.11.1)", "pyyaml (==5.1)", "pyyaml-env-tag (==0.1)", "watchdog (==2.0)"] - -[[package]] -name = "mkdocs-get-deps" -version = "0.2.0" -description = "MkDocs extension that lists all dependencies according to a mkdocs.yml file" -optional = false -python-versions = ">=3.8" -groups = ["docs"] -files = [ - {file = "mkdocs_get_deps-0.2.0-py3-none-any.whl", hash = "sha256:2bf11d0b133e77a0dd036abeeb06dec8775e46efa526dc70667d8863eefc6134"}, - {file = "mkdocs_get_deps-0.2.0.tar.gz", hash = "sha256:162b3d129c7fad9b19abfdcb9c1458a651628e4b1dea628ac68790fb3061c60c"}, -] - -[package.dependencies] -importlib-metadata = {version = ">=4.3", markers = "python_version < \"3.10\""} -mergedeep = ">=1.3.4" -platformdirs = ">=2.2.0" -pyyaml = ">=5.1" - -[[package]] -name = "mkdocs-git-revision-date-localized-plugin" -version = "1.4.1" -description = "Mkdocs plugin that enables displaying the localized date of the last git modification of a markdown file." -optional = false -python-versions = ">=3.8" -groups = ["docs"] -files = [ - {file = "mkdocs_git_revision_date_localized_plugin-1.4.1-py3-none-any.whl", hash = "sha256:bb1eca7f156e0c8a587167662923d76efed7f7e0c06b84471aa5ae72a744a434"}, - {file = "mkdocs_git_revision_date_localized_plugin-1.4.1.tar.gz", hash = "sha256:364d7c4c45c4f333c750e34bc298ac685a7a8bf9b7b52890d52b2f90f1812c4b"}, -] - -[package.dependencies] -babel = ">=2.7.0" -gitpython = ">=3.1.44" -mkdocs = ">=1.0" -pytz = ">=2025.1" - -[[package]] -name = "mkdocs-material" -version = "9.6.5" -description = "Documentation that simply works" -optional = false -python-versions = ">=3.8" -groups = ["docs"] -files = [ - {file = "mkdocs_material-9.6.5-py3-none-any.whl", hash = "sha256:aad3e6fb860c20870f75fb2a69ef901f1be727891e41adb60b753efcae19453b"}, - {file = "mkdocs_material-9.6.5.tar.gz", hash = "sha256:b714679a8c91b0ffe2188e11ed58c44d2523e9c2ae26a29cc652fa7478faa21f"}, -] - -[package.dependencies] -babel = ">=2.10,<3.0" -colorama = ">=0.4,<1.0" -jinja2 = ">=3.0,<4.0" -markdown = ">=3.2,<4.0" -mkdocs = ">=1.6,<2.0" -mkdocs-material-extensions = ">=1.3,<2.0" -paginate = ">=0.5,<1.0" -pygments = ">=2.16,<3.0" -pymdown-extensions = ">=10.2,<11.0" -regex = ">=2022.4" -requests = ">=2.26,<3.0" - -[package.extras] -git = ["mkdocs-git-committers-plugin-2 (>=1.1,<3)", "mkdocs-git-revision-date-localized-plugin (>=1.2.4,<2.0)"] -imaging = ["cairosvg (>=2.6,<3.0)", "pillow (>=10.2,<11.0)"] -recommended = ["mkdocs-minify-plugin (>=0.7,<1.0)", "mkdocs-redirects (>=1.2,<2.0)", "mkdocs-rss-plugin (>=1.6,<2.0)"] - -[[package]] -name = "mkdocs-material-extensions" -version = "1.3.1" -description = "Extension pack for Python Markdown and MkDocs Material." -optional = false -python-versions = ">=3.8" -groups = ["docs"] -files = [ - {file = "mkdocs_material_extensions-1.3.1-py3-none-any.whl", hash = "sha256:adff8b62700b25cb77b53358dad940f3ef973dd6db797907c49e3c2ef3ab4e31"}, - {file = "mkdocs_material_extensions-1.3.1.tar.gz", hash = "sha256:10c9511cea88f568257f960358a467d12b970e1f7b2c0e5fb2bb48cab1928443"}, -] - [[package]] name = "mock" version = "5.2.0" @@ -3582,28 +3394,12 @@ version = "25.0" description = "Core utilities for Python packages" optional = false python-versions = ">=3.8" -groups = ["main", "dev", "docs"] +groups = ["main", "dev"] files = [ {file = "packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484"}, {file = "packaging-25.0.tar.gz", hash = "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f"}, ] -[[package]] -name = "paginate" -version = "0.5.7" -description = "Divides large result sets into pages for easier browsing" -optional = false -python-versions = "*" -groups = ["docs"] -files = [ - {file = "paginate-0.5.7-py2.py3-none-any.whl", hash = "sha256:b885e2af73abcf01d9559fd5216b57ef722f8c42affbb63942377668e35c7591"}, - {file = "paginate-0.5.7.tar.gz", hash = "sha256:22bd083ab41e1a8b4f3690544afb2c60c25e5c9a63a30fa2f483f6c60c8e5945"}, -] - -[package.extras] -dev = ["pytest", "tox"] -lint = ["black"] - [[package]] name = "pandas" version = "2.2.3" @@ -3709,7 +3505,7 @@ version = "0.12.1" description = "Utility library for gitignore style pattern matching of file paths." optional = false python-versions = ">=3.8" -groups = ["dev", "docs"] +groups = ["dev"] files = [ {file = "pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08"}, {file = "pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712"}, @@ -3736,7 +3532,7 @@ version = "4.3.8" description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." optional = false python-versions = ">=3.9" -groups = ["dev", "docs"] +groups = ["dev"] files = [ {file = "platformdirs-4.3.8-py3-none-any.whl", hash = "sha256:ff7059bb7eb1179e2685604f4aaf157cfd9535242bd23742eadc3c13542139b4"}, {file = "platformdirs-4.3.8.tar.gz", hash = "sha256:3d512d96e16bcb959a814c9f348431070822a6496326a4be0911c40b5a74c2bc"}, @@ -4264,7 +4060,7 @@ version = "2.19.2" description = "Pygments is a syntax highlighting package written in Python." optional = false python-versions = ">=3.8" -groups = ["dev", "docs"] +groups = ["dev"] files = [ {file = "pygments-2.19.2-py3-none-any.whl", hash = "sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b"}, {file = "pygments-2.19.2.tar.gz", hash = "sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887"}, @@ -4325,25 +4121,6 @@ typing-extensions = {version = ">=3.10.0", markers = "python_version < \"3.10\"" spelling = ["pyenchant (>=3.2,<4.0)"] testutils = ["gitpython (>3)"] -[[package]] -name = "pymdown-extensions" -version = "10.16" -description = "Extension pack for Python Markdown." -optional = false -python-versions = ">=3.9" -groups = ["docs"] -files = [ - {file = "pymdown_extensions-10.16-py3-none-any.whl", hash = "sha256:f5dd064a4db588cb2d95229fc4ee63a1b16cc8b4d0e6145c0899ed8723da1df2"}, - {file = "pymdown_extensions-10.16.tar.gz", hash = "sha256:71dac4fca63fabeffd3eb9038b756161a33ec6e8d230853d3cecf562155ab3de"}, -] - -[package.dependencies] -markdown = ">=3.6" -pyyaml = "*" - -[package.extras] -extra = ["pygments (>=2.19.1)"] - [[package]] name = "pynacl" version = "1.5.0" @@ -4509,7 +4286,7 @@ version = "2.9.0.post0" description = "Extensions to the standard Python datetime module" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" -groups = ["main", "dev", "docs"] +groups = ["main", "dev"] files = [ {file = "python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3"}, {file = "python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"}, @@ -4524,7 +4301,7 @@ version = "2025.1" description = "World timezone definitions, modern and historical" optional = false python-versions = "*" -groups = ["main", "docs"] +groups = ["main"] files = [ {file = "pytz-2025.1-py2.py3-none-any.whl", hash = "sha256:89dd22dca55b46eac6eda23b2d72721bf1bdfef212645d81513ef5d03038de57"}, {file = "pytz-2025.1.tar.gz", hash = "sha256:c2db42be2a2518b28e65f9207c4d05e6ff547d1efa4086469ef855e4ab70178e"}, @@ -4567,7 +4344,7 @@ version = "6.0.2" description = "YAML parser and emitter for Python" optional = false python-versions = ">=3.8" -groups = ["main", "dev", "docs"] +groups = ["main", "dev"] files = [ {file = "PyYAML-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086"}, {file = "PyYAML-6.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf"}, @@ -4624,21 +4401,6 @@ files = [ {file = "pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e"}, ] -[[package]] -name = "pyyaml-env-tag" -version = "1.1" -description = "A custom YAML tag for referencing environment variables in YAML files." -optional = false -python-versions = ">=3.9" -groups = ["docs"] -files = [ - {file = "pyyaml_env_tag-1.1-py3-none-any.whl", hash = "sha256:17109e1a528561e32f026364712fee1264bc2ea6715120891174ed1b980d2e04"}, - {file = "pyyaml_env_tag-1.1.tar.gz", hash = "sha256:2eb38b75a2d21ee0475d6d97ec19c63287a7e140231e4214969d0eac923cd7ff"}, -] - -[package.dependencies] -pyyaml = "*" - [[package]] name = "referencing" version = "0.36.2" @@ -4662,7 +4424,7 @@ version = "2024.11.6" description = "Alternative regular expression module, to replace re." optional = false python-versions = ">=3.8" -groups = ["dev", "docs"] +groups = ["dev"] files = [ {file = "regex-2024.11.6-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ff590880083d60acc0433f9c3f713c51f7ac6ebb9adf889c79a261ecf541aa91"}, {file = "regex-2024.11.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:658f90550f38270639e83ce492f27d2c8d2cd63805c65a13a14d36ca126753f0"}, @@ -4766,7 +4528,7 @@ version = "2.32.4" description = "Python HTTP for Humans." optional = false python-versions = ">=3.8" -groups = ["main", "dev", "docs"] +groups = ["main", "dev"] files = [ {file = "requests-2.32.4-py3-none-any.whl", hash = "sha256:27babd3cda2a6d50b30443204ee89830707d396671944c998b5975b031ac2b2c"}, {file = "requests-2.32.4.tar.gz", hash = "sha256:27d0316682c8a29834d3264820024b62a36942083d52caf2f14c0591336d3422"}, @@ -5085,6 +4847,7 @@ files = [ {file = "ruamel.yaml.clib-0.2.12-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f66efbc1caa63c088dead1c4170d148eabc9b80d95fb75b6c92ac0aad2437d76"}, {file = "ruamel.yaml.clib-0.2.12-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:22353049ba4181685023b25b5b51a574bce33e7f51c759371a7422dcae5402a6"}, {file = "ruamel.yaml.clib-0.2.12-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:932205970b9f9991b34f55136be327501903f7c66830e9760a8ffb15b07f05cd"}, + {file = "ruamel.yaml.clib-0.2.12-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:a52d48f4e7bf9005e8f0a89209bf9a73f7190ddf0489eee5eb51377385f59f2a"}, {file = "ruamel.yaml.clib-0.2.12-cp310-cp310-win32.whl", hash = "sha256:3eac5a91891ceb88138c113f9db04f3cebdae277f5d44eaa3651a4f573e6a5da"}, {file = "ruamel.yaml.clib-0.2.12-cp310-cp310-win_amd64.whl", hash = "sha256:ab007f2f5a87bd08ab1499bdf96f3d5c6ad4dcfa364884cb4549aa0154b13a28"}, {file = "ruamel.yaml.clib-0.2.12-cp311-cp311-macosx_13_0_arm64.whl", hash = "sha256:4a6679521a58256a90b0d89e03992c15144c5f3858f40d7c18886023d7943db6"}, @@ -5093,6 +4856,7 @@ files = [ {file = "ruamel.yaml.clib-0.2.12-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:811ea1594b8a0fb466172c384267a4e5e367298af6b228931f273b111f17ef52"}, {file = "ruamel.yaml.clib-0.2.12-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:cf12567a7b565cbf65d438dec6cfbe2917d3c1bdddfce84a9930b7d35ea59642"}, {file = "ruamel.yaml.clib-0.2.12-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:7dd5adc8b930b12c8fc5b99e2d535a09889941aa0d0bd06f4749e9a9397c71d2"}, + {file = "ruamel.yaml.clib-0.2.12-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1492a6051dab8d912fc2adeef0e8c72216b24d57bd896ea607cb90bb0c4981d3"}, {file = "ruamel.yaml.clib-0.2.12-cp311-cp311-win32.whl", hash = "sha256:bd0a08f0bab19093c54e18a14a10b4322e1eacc5217056f3c063bd2f59853ce4"}, {file = "ruamel.yaml.clib-0.2.12-cp311-cp311-win_amd64.whl", hash = "sha256:a274fb2cb086c7a3dea4322ec27f4cb5cc4b6298adb583ab0e211a4682f241eb"}, {file = "ruamel.yaml.clib-0.2.12-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:20b0f8dc160ba83b6dcc0e256846e1a02d044e13f7ea74a3d1d56ede4e48c632"}, @@ -5101,6 +4865,7 @@ files = [ {file = "ruamel.yaml.clib-0.2.12-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:749c16fcc4a2b09f28843cda5a193e0283e47454b63ec4b81eaa2242f50e4ccd"}, {file = "ruamel.yaml.clib-0.2.12-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:bf165fef1f223beae7333275156ab2022cffe255dcc51c27f066b4370da81e31"}, {file = "ruamel.yaml.clib-0.2.12-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:32621c177bbf782ca5a18ba4d7af0f1082a3f6e517ac2a18b3974d4edf349680"}, + {file = "ruamel.yaml.clib-0.2.12-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:b82a7c94a498853aa0b272fd5bc67f29008da798d4f93a2f9f289feb8426a58d"}, {file = "ruamel.yaml.clib-0.2.12-cp312-cp312-win32.whl", hash = "sha256:e8c4ebfcfd57177b572e2040777b8abc537cdef58a2120e830124946aa9b42c5"}, {file = "ruamel.yaml.clib-0.2.12-cp312-cp312-win_amd64.whl", hash = "sha256:0467c5965282c62203273b838ae77c0d29d7638c8a4e3a1c8bdd3602c10904e4"}, {file = "ruamel.yaml.clib-0.2.12-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:4c8c5d82f50bb53986a5e02d1b3092b03622c02c2eb78e29bec33fd9593bae1a"}, @@ -5109,6 +4874,7 @@ files = [ {file = "ruamel.yaml.clib-0.2.12-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:96777d473c05ee3e5e3c3e999f5d23c6f4ec5b0c38c098b3a5229085f74236c6"}, {file = "ruamel.yaml.clib-0.2.12-cp313-cp313-musllinux_1_1_i686.whl", hash = "sha256:3bc2a80e6420ca8b7d3590791e2dfc709c88ab9152c00eeb511c9875ce5778bf"}, {file = "ruamel.yaml.clib-0.2.12-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:e188d2699864c11c36cdfdada94d781fd5d6b0071cd9c427bceb08ad3d7c70e1"}, + {file = "ruamel.yaml.clib-0.2.12-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:4f6f3eac23941b32afccc23081e1f50612bdbe4e982012ef4f5797986828cd01"}, {file = "ruamel.yaml.clib-0.2.12-cp313-cp313-win32.whl", hash = "sha256:6442cb36270b3afb1b4951f060eccca1ce49f3d087ca1ca4563a6eb479cb3de6"}, {file = "ruamel.yaml.clib-0.2.12-cp313-cp313-win_amd64.whl", hash = "sha256:e5b8daf27af0b90da7bb903a876477a9e6d7270be6146906b276605997c7e9a3"}, {file = "ruamel.yaml.clib-0.2.12-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:fc4b630cd3fa2cf7fce38afa91d7cfe844a9f75d7f0f36393fa98815e911d987"}, @@ -5117,6 +4883,7 @@ files = [ {file = "ruamel.yaml.clib-0.2.12-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e2f1c3765db32be59d18ab3953f43ab62a761327aafc1594a2a1fbe038b8b8a7"}, {file = "ruamel.yaml.clib-0.2.12-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:d85252669dc32f98ebcd5d36768f5d4faeaeaa2d655ac0473be490ecdae3c285"}, {file = "ruamel.yaml.clib-0.2.12-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:e143ada795c341b56de9418c58d028989093ee611aa27ffb9b7f609c00d813ed"}, + {file = "ruamel.yaml.clib-0.2.12-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2c59aa6170b990d8d2719323e628aaf36f3bfbc1c26279c0eeeb24d05d2d11c7"}, {file = "ruamel.yaml.clib-0.2.12-cp39-cp39-win32.whl", hash = "sha256:beffaed67936fbbeffd10966a4eb53c402fafd3d6833770516bf7314bc6ffa12"}, {file = "ruamel.yaml.clib-0.2.12-cp39-cp39-win_amd64.whl", hash = "sha256:040ae85536960525ea62868b642bdb0c2cc6021c9f9d507810c0c604e66f5a7b"}, {file = "ruamel.yaml.clib-0.2.12.tar.gz", hash = "sha256:6c8fbb13ec503f99a91901ab46e0b07ae7941cd527393187039aec586fdfd36f"}, @@ -5268,7 +5035,7 @@ version = "1.17.0" description = "Python 2 and 3 compatibility utilities" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" -groups = ["main", "dev", "docs"] +groups = ["main", "dev"] files = [ {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"}, {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"}, @@ -5289,18 +5056,6 @@ files = [ [package.extras] optional = ["SQLAlchemy (>=1.4,<3)", "aiodns (>1.0)", "aiohttp (>=3.7.3,<4)", "boto3 (<=2)", "websocket-client (>=1,<2)", "websockets (>=9.1,<15)"] -[[package]] -name = "smmap" -version = "5.0.2" -description = "A pure Python implementation of a sliding window memory map manager" -optional = false -python-versions = ">=3.7" -groups = ["docs"] -files = [ - {file = "smmap-5.0.2-py3-none-any.whl", hash = "sha256:b30115f0def7d7531d22a0fb6502488d879e75b260a9db4d0819cfb25403af5e"}, - {file = "smmap-5.0.2.tar.gz", hash = "sha256:26ea65a03958fa0c8a1c7e8c7a58fdc77221b8910f6be2131affade476898ad5"}, -] - [[package]] name = "sniffio" version = "1.3.1" @@ -5474,12 +5229,11 @@ version = "4.14.1" description = "Backported and Experimental Type Hints for Python 3.9+" optional = false python-versions = ">=3.9" -groups = ["main", "dev", "docs"] +groups = ["main", "dev"] files = [ {file = "typing_extensions-4.14.1-py3-none-any.whl", hash = "sha256:d1e1e3b58374dc93031d6eda2420a48ea44a36c2b4766a4fdeb3710755731d76"}, {file = "typing_extensions-4.14.1.tar.gz", hash = "sha256:38b39f4aeeab64884ce9f74c94263ef78f3c22467c8724005483154c26648d36"}, ] -markers = {docs = "python_version < \"3.10\""} [[package]] name = "typing-inspection" @@ -5544,7 +5298,7 @@ version = "1.26.20" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" -groups = ["main", "dev", "docs"] +groups = ["main", "dev"] markers = "python_version < \"3.10\"" files = [ {file = "urllib3-1.26.20-py2.py3-none-any.whl", hash = "sha256:0ed14ccfbf1c30a9072c7ca157e4319b70d65f623e91e7b32fadb2853431016e"}, @@ -5562,7 +5316,7 @@ version = "2.5.0" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false python-versions = ">=3.9" -groups = ["main", "dev", "docs"] +groups = ["main", "dev"] markers = "python_version >= \"3.10\"" files = [ {file = "urllib3-2.5.0-py3-none-any.whl", hash = "sha256:e6b01673c0fa6a13e374b50871808eb3bf7046c4b125b216f6bf1cc604cff0dc"}, @@ -5611,49 +5365,6 @@ files = [ [package.dependencies] tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} -[[package]] -name = "watchdog" -version = "6.0.0" -description = "Filesystem events monitoring" -optional = false -python-versions = ">=3.9" -groups = ["docs"] -files = [ - {file = "watchdog-6.0.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d1cdb490583ebd691c012b3d6dae011000fe42edb7a82ece80965b42abd61f26"}, - {file = "watchdog-6.0.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:bc64ab3bdb6a04d69d4023b29422170b74681784ffb9463ed4870cf2f3e66112"}, - {file = "watchdog-6.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c897ac1b55c5a1461e16dae288d22bb2e412ba9807df8397a635d88f671d36c3"}, - {file = "watchdog-6.0.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:6eb11feb5a0d452ee41f824e271ca311a09e250441c262ca2fd7ebcf2461a06c"}, - {file = "watchdog-6.0.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ef810fbf7b781a5a593894e4f439773830bdecb885e6880d957d5b9382a960d2"}, - {file = "watchdog-6.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:afd0fe1b2270917c5e23c2a65ce50c2a4abb63daafb0d419fde368e272a76b7c"}, - {file = "watchdog-6.0.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:bdd4e6f14b8b18c334febb9c4425a878a2ac20efd1e0b231978e7b150f92a948"}, - {file = "watchdog-6.0.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:c7c15dda13c4eb00d6fb6fc508b3c0ed88b9d5d374056b239c4ad1611125c860"}, - {file = "watchdog-6.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6f10cb2d5902447c7d0da897e2c6768bca89174d0c6e1e30abec5421af97a5b0"}, - {file = "watchdog-6.0.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:490ab2ef84f11129844c23fb14ecf30ef3d8a6abafd3754a6f75ca1e6654136c"}, - {file = "watchdog-6.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:76aae96b00ae814b181bb25b1b98076d5fc84e8a53cd8885a318b42b6d3a5134"}, - {file = "watchdog-6.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a175f755fc2279e0b7312c0035d52e27211a5bc39719dd529625b1930917345b"}, - {file = "watchdog-6.0.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:e6f0e77c9417e7cd62af82529b10563db3423625c5fce018430b249bf977f9e8"}, - {file = "watchdog-6.0.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:90c8e78f3b94014f7aaae121e6b909674df5b46ec24d6bebc45c44c56729af2a"}, - {file = "watchdog-6.0.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e7631a77ffb1f7d2eefa4445ebbee491c720a5661ddf6df3498ebecae5ed375c"}, - {file = "watchdog-6.0.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:c7ac31a19f4545dd92fc25d200694098f42c9a8e391bc00bdd362c5736dbf881"}, - {file = "watchdog-6.0.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:9513f27a1a582d9808cf21a07dae516f0fab1cf2d7683a742c498b93eedabb11"}, - {file = "watchdog-6.0.0-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:7a0e56874cfbc4b9b05c60c8a1926fedf56324bb08cfbc188969777940aef3aa"}, - {file = "watchdog-6.0.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:e6439e374fc012255b4ec786ae3c4bc838cd7309a540e5fe0952d03687d8804e"}, - {file = "watchdog-6.0.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:7607498efa04a3542ae3e05e64da8202e58159aa1fa4acddf7678d34a35d4f13"}, - {file = "watchdog-6.0.0-py3-none-manylinux2014_armv7l.whl", hash = "sha256:9041567ee8953024c83343288ccc458fd0a2d811d6a0fd68c4c22609e3490379"}, - {file = "watchdog-6.0.0-py3-none-manylinux2014_i686.whl", hash = "sha256:82dc3e3143c7e38ec49d61af98d6558288c415eac98486a5c581726e0737c00e"}, - {file = "watchdog-6.0.0-py3-none-manylinux2014_ppc64.whl", hash = "sha256:212ac9b8bf1161dc91bd09c048048a95ca3a4c4f5e5d4a7d1b1a7d5752a7f96f"}, - {file = "watchdog-6.0.0-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:e3df4cbb9a450c6d49318f6d14f4bbc80d763fa587ba46ec86f99f9e6876bb26"}, - {file = "watchdog-6.0.0-py3-none-manylinux2014_s390x.whl", hash = "sha256:2cce7cfc2008eb51feb6aab51251fd79b85d9894e98ba847408f662b3395ca3c"}, - {file = "watchdog-6.0.0-py3-none-manylinux2014_x86_64.whl", hash = "sha256:20ffe5b202af80ab4266dcd3e91aae72bf2da48c0d33bdb15c66658e685e94e2"}, - {file = "watchdog-6.0.0-py3-none-win32.whl", hash = "sha256:07df1fdd701c5d4c8e55ef6cf55b8f0120fe1aef7ef39a1c6fc6bc2e606d517a"}, - {file = "watchdog-6.0.0-py3-none-win_amd64.whl", hash = "sha256:cbafb470cf848d93b5d013e2ecb245d4aa1c8fd0504e863ccefa32445359d680"}, - {file = "watchdog-6.0.0-py3-none-win_ia64.whl", hash = "sha256:a1914259fa9e1454315171103c6a30961236f508b9b623eae470268bbcc6a22f"}, - {file = "watchdog-6.0.0.tar.gz", hash = "sha256:9ddf7c82fda3ae8e24decda1338ede66e1c99883db93711d8fb941eaa2d8c282"}, -] - -[package.extras] -watchmedo = ["PyYAML (>=3.10)"] - [[package]] name = "websocket-client" version = "1.8.0" @@ -5927,12 +5638,12 @@ version = "3.23.0" description = "Backport of pathlib-compatible object wrapper for zip files" optional = false python-versions = ">=3.9" -groups = ["main", "dev", "docs"] +groups = ["main", "dev"] files = [ {file = "zipp-3.23.0-py3-none-any.whl", hash = "sha256:071652d6115ed432f5ce1d34c336c0adfd6a884660d1e9712a256d3d3bd4b14e"}, {file = "zipp-3.23.0.tar.gz", hash = "sha256:a07157588a12518c9d4034df3fbbee09c814741a33ff63c05fa29d26a2404166"}, ] -markers = {dev = "python_version < \"3.10\"", docs = "python_version < \"3.10\""} +markers = {dev = "python_version < \"3.10\""} [package.extras] check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1) ; sys_platform != \"cygwin\""] @@ -5945,4 +5656,4 @@ type = ["pytest-mypy"] [metadata] lock-version = "2.1" python-versions = ">3.9.1,<3.13" -content-hash = "c2fb8567f1a6be319ae73f8c3a30e7b5be6f6fc65deee567d2a9e09eadd984c9" +content-hash = "ea79d82b4e255ec4604f440a507da6dac38b57af93356761ac793678aa615cf5" diff --git a/prowler/CHANGELOG.md b/prowler/CHANGELOG.md index d097baaf59..712c53ac25 100644 --- a/prowler/CHANGELOG.md +++ b/prowler/CHANGELOG.md @@ -32,12 +32,17 @@ All notable changes to the **Prowler SDK** are documented in this file. - Update AWS AppStream service metadata to new format [(#8789)](https://github.com/prowler-cloud/prowler/pull/8789) - Update AWS API Gateway service metadata to new format [(#8788)](https://github.com/prowler-cloud/prowler/pull/8788) - Update AWS Athena service metadata to new format [(#8790)](https://github.com/prowler-cloud/prowler/pull/8790) +- Update AWS CloudTrail service metadata to new format [(#8831)](https://github.com/prowler-cloud/prowler/pull/8831) - Update AWS Auto Scaling service metadata to new format [(#8824)](https://github.com/prowler-cloud/prowler/pull/8824) - Update AWS Backup service metadata to new format [(#8826)](https://github.com/prowler-cloud/prowler/pull/8826) - Update AWS CloudFormation service metadata to new format [(#8828)](https://github.com/prowler-cloud/prowler/pull/8828) - Update AWS Lambda service metadata to new format [(#8825)](https://github.com/prowler-cloud/prowler/pull/8825) +- Update AWS DLM service metadata to new format [(#8860)](https://github.com/prowler-cloud/prowler/pull/8860) +- Update AWS DMS service metadata to new format [(#8861)](https://github.com/prowler-cloud/prowler/pull/8861) +- Update AWS Directory Service service metadata to new format [(#8859)](https://github.com/prowler-cloud/prowler/pull/8859) - Update AWS CloudFront service metadata to new format [(#8829)](https://github.com/prowler-cloud/prowler/pull/8829) - Deprecate user authentication for M365 provider [(#8865)](https://github.com/prowler-cloud/prowler/pull/8865) +- Update AWS EFS service metadata to new format [(#8889)](https://github.com/prowler-cloud/prowler/pull/8889) ### Fixed - Fix SNS topics showing empty AWS_ResourceID in Quick Inventory output [(#8762)](https://github.com/prowler-cloud/prowler/issues/8762) @@ -45,6 +50,7 @@ All notable changes to the **Prowler SDK** are documented in this file. - Prowler ThreatScore scoring calculation CLI [(#8582)](https://github.com/prowler-cloud/prowler/pull/8582) - Add missing attributes for Mitre Attack AWS, Azure and GCP [(#8907)](https://github.com/prowler-cloud/prowler/pull/8907) - Fix KeyError in CloudSQL and Monitoring services in GCP provider [(#8909)](https://github.com/prowler-cloud/prowler/pull/8909) +- Fix ResourceName in GCP provider [(#8928)](https://github.com/prowler-cloud/prowler/pull/8928) --- diff --git a/prowler/compliance/aws/ccc_aws.json b/prowler/compliance/aws/ccc_aws.json index ba00424a72..1f6da6d5f6 100644 --- a/prowler/compliance/aws/ccc_aws.json +++ b/prowler/compliance/aws/ccc_aws.json @@ -6,19 +6,19 @@ "Description": "Common Cloud Controls Catalog (CCC) for AWS", "Requirements": [ { - "Id": "CCC.AuditLog.C01.TR01", + "Id": "CCC.AuditLog.CN01.AR01", "Description": "When the signature validation process is performed, then it MUST detect any modification of data.", "Attributes": [ { "FamilyName": "Integrity", "FamilyDescription": "Controls designed to protected the integrity of Audit Log data.", - "Section": "CCC.AuditLog.C01 Implement Digital Signatures With Hash Chaining", + "Section": "CCC.AuditLog.CN01 Implement Digital Signatures With Hash Chaining", "SubSection": "", - "SubSectionObjective": "Digital signatures allows for external verification of log data tampering and\nhash chaining allows for deleted log files to be detected.", + "SubSectionObjective": "Digital signatures allows for external verification of log data tampering and hash chaining allows for deleted log files to be detected.", "Applicability": [ "tlp-red" ], - "Recommendation": "Ensure hash of data is included in digital signature.\n", + "Recommendation": "Ensure hash of data is included in digital signature. ", "SectionThreatMappings": [ { "ReferenceId": "CCC", @@ -49,19 +49,19 @@ ] }, { - "Id": "CCC.AuditLog.C01.TR02", + "Id": "CCC.AuditLog.CN01.AR02", "Description": "When the signature validation process is performed, then it MUST detect any missing (deleted) log file.", "Attributes": [ { "FamilyName": "Integrity", "FamilyDescription": "Controls designed to protected the integrity of Audit Log data.", - "Section": "CCC.AuditLog.C01 Implement Digital Signatures With Hash Chaining", + "Section": "CCC.AuditLog.CN01 Implement Digital Signatures With Hash Chaining", "SubSection": "", - "SubSectionObjective": "Digital signatures allows for external verification of log data tampering and\nhash chaining allows for deleted log files to be detected.", + "SubSectionObjective": "Digital signatures allows for external verification of log data tampering and hash chaining allows for deleted log files to be detected.", "Applicability": [ "tlp-red" ], - "Recommendation": "Ensure verification process includes a chained hash function.\n", + "Recommendation": "Ensure verification process includes a chained hash function. ", "SectionThreatMappings": [ { "ReferenceId": "CCC", @@ -92,15 +92,15 @@ ] }, { - "Id": "CCC.AuditLog.C02.TR01", - "Description": "When a manual action is performed to generate each audit log type,\nthen the corresponding audit log type MUST be generated and recorded.", + "Id": "CCC.AuditLog.CN02.AR01", + "Description": "When a manual action is performed to generate each audit log type, then the corresponding audit log type MUST be generated and recorded.", "Attributes": [ { "FamilyName": "Integrity", "FamilyDescription": "Controls designed to protected the integrity of Audit Log data.", - "Section": "CCC.AuditLog.C02 Enable And Validate All Audit Log Types", + "Section": "CCC.AuditLog.CN02 Enable And Validate All Audit Log Types", "SubSection": "", - "SubSectionObjective": "Review audit log configuration and ensure that all audit log types\nare being generated and replicated to configured sinks", + "SubSectionObjective": "Review audit log configuration and ensure that all audit log types are being generated and replicated to configured sinks", "Applicability": [ "tlp-red", "tlp-amber" @@ -149,20 +149,20 @@ ] }, { - "Id": "CCC.AuditLog.C03.TR01", + "Id": "CCC.AuditLog.CN03.AR01", "Description": "When an attempt is made to disable a log source, then an alert MUST be generated.", "Attributes": [ { "FamilyName": "Integrity", "FamilyDescription": "Controls designed to protected the integrity of Audit Log data.", - "Section": "CCC.AuditLog.C03 Alert On Audit Log Changes And Access", + "Section": "CCC.AuditLog.CN03 Alert On Audit Log Changes And Access", "SubSection": "", - "SubSectionObjective": "Ensure that specific alerts have been configured to detect changes in\naudit log configuration such as disabling exporting of logs.\nAlerts MUST also be created to detect changes in retention/object lock policies\nfor exported data log sources/buckets.", + "SubSectionObjective": "Ensure that specific alerts have been configured to detect changes in audit log configuration such as disabling exporting of logs. Alerts MUST also be created to detect changes in retention/object lock policies for exported data log sources/buckets.", "Applicability": [ "tlp-red", "tlp-amber" ], - "Recommendation": "Ensure alerting is correctly configured\n", + "Recommendation": "Ensure alerting is correctly configured ", "SectionThreatMappings": [ { "ReferenceId": "CCC", @@ -200,20 +200,20 @@ ] }, { - "Id": "CCC.AuditLog.C03.TR02", - "Description": "When an attempt is made to alter the retention or object lock status\nof an external data log source or bucket, then an alert MUST be generated.", + "Id": "CCC.AuditLog.CN03.AR02", + "Description": "When an attempt is made to alter the retention or object lock status of an external data log source or bucket, then an alert MUST be generated.", "Attributes": [ { "FamilyName": "Integrity", "FamilyDescription": "Controls designed to protected the integrity of Audit Log data.", - "Section": "CCC.AuditLog.C03 Alert On Audit Log Changes And Access", + "Section": "CCC.AuditLog.CN03 Alert On Audit Log Changes And Access", "SubSection": "", - "SubSectionObjective": "Ensure that specific alerts have been configured to detect changes in\naudit log configuration such as disabling exporting of logs.\nAlerts MUST also be created to detect changes in retention/object lock policies\nfor exported data log sources/buckets.", + "SubSectionObjective": "Ensure that specific alerts have been configured to detect changes in audit log configuration such as disabling exporting of logs. Alerts MUST also be created to detect changes in retention/object lock policies for exported data log sources/buckets.", "Applicability": [ "tlp-red", "tlp-amber" ], - "Recommendation": "Ensure alerting is correctly configured\n", + "Recommendation": "Ensure alerting is correctly configured ", "SectionThreatMappings": [ { "ReferenceId": "CCC", @@ -254,20 +254,20 @@ ] }, { - "Id": "CCC.AuditLog.C04.TR01", - "Description": "When audit log buckets are created then verify that server access\nlogging MUST be enabled for the audit log bucket,\nwith logs delivered to a separate, secure logging bucket.", + "Id": "CCC.AuditLog.CN04.AR01", + "Description": "When audit log buckets are created then verify that server access logging MUST be enabled for the audit log bucket, with logs delivered to a separate, secure logging bucket.", "Attributes": [ { "FamilyName": "Integrity", "FamilyDescription": "Controls designed to protected the integrity of Audit Log data.", - "Section": "CCC.AuditLog.C04 Ensure Access Logging Is Enabled on the Audit Log Bucket", + "Section": "CCC.AuditLog.CN04 Ensure Access Logging Is Enabled on the Audit Log Bucket", "SubSection": "", - "SubSectionObjective": "Ensure that access logging is enabled for the audit log storage bucket to\ncapture all requests made to the bucket, providing an audit trail of data access.", + "SubSectionObjective": "Ensure that access logging is enabled for the audit log storage bucket to capture all requests made to the bucket, providing an audit trail of data access.", "Applicability": [ "tlp-red", "tlp-amber" ], - "Recommendation": "Configure the audit log bucket to enable server access logging.\nEnsure the target logging bucket is configured for appropriate security,\nincluding restricted access and immutability.\n", + "Recommendation": "Configure the audit log bucket to enable server access logging. Ensure the target logging bucket is configured for appropriate security, including restricted access and immutability. ", "SectionThreatMappings": [ { "ReferenceId": "CCC", @@ -303,20 +303,20 @@ ] }, { - "Id": "CCC.AuditLog.C05.TR01", + "Id": "CCC.AuditLog.CN05.AR01", "Description": "When audit logs are exported, then audit logs MUST be present in the configured data location.", "Attributes": [ { "FamilyName": "Availability", "FamilyDescription": "Controls designed to protected the availability of Audit Log data.", - "Section": "CCC.AuditLog.C05 Export Audit Logs To Bucket", + "Section": "CCC.AuditLog.CN05 Export Audit Logs To Bucket", "SubSection": "", - "SubSectionObjective": "Configure audit logs to be sent to a external bucket where they can be globally replicated\nand can be subject to greater access control and data retention polices.", + "SubSectionObjective": "Configure audit logs to be sent to a external bucket where they can be globally replicated and can be subject to greater access control and data retention polices.", "Applicability": [ "tlp-red", "tlp-amber" ], - "Recommendation": "Configure audit log exporting.\n", + "Recommendation": "Configure audit log exporting. ", "SectionThreatMappings": [ { "ReferenceId": "CCC", @@ -357,21 +357,21 @@ ] }, { - "Id": "CCC.AuditLog.C06.TR01", - "Description": "When the retention policy is applied, then data MUST\nbe automatically deleted after the configured number of days.", + "Id": "CCC.AuditLog.CN06.AR01", + "Description": "When the retention policy is applied, then data MUST be automatically deleted after the configured number of days.", "Attributes": [ { "FamilyName": "Availability", "FamilyDescription": "Controls designed to protected the availability of Audit Log data.", - "Section": "CCC.AuditLog.C06 Enforce Retention Policy on Audit Log Bucket", + "Section": "CCC.AuditLog.CN06 Enforce Retention Policy on Audit Log Bucket", "SubSection": "", - "SubSectionObjective": "Configure a custom retention policy on the designated audit log bucket to ensure that logs are\nretained for the correct number of days as defined by your organization's policy.", + "SubSectionObjective": "Configure a custom retention policy on the designated audit log bucket to ensure that logs are retained for the correct number of days as defined by your organization's policy.", "Applicability": [ "tlp-red", "tlp-amber", "tlp-green" ], - "Recommendation": "Configure the audit log bucket's lifecycle rules or object retention settings to enforce\nthe required data retention period.\n", + "Recommendation": "Configure the audit log bucket's lifecycle rules or object retention settings to enforce the required data retention period. ", "SectionThreatMappings": [ { "ReferenceId": "CCC", @@ -403,21 +403,21 @@ ] }, { - "Id": "CCC.AuditLog.C07.TR01", - "Description": "When a standard file deletion is attempted on an object within\nthe audit log bucket, then it MUST be prevented unless MFA is provided.", + "Id": "CCC.AuditLog.CN07.AR01", + "Description": "When a standard file deletion is attempted on an object within the audit log bucket, then it MUST be prevented unless MFA is provided.", "Attributes": [ { "FamilyName": "Availability", "FamilyDescription": "Controls designed to protected the availability of Audit Log data.", - "Section": "CCC.AuditLog.C07 Enforce MFA Delete on Audit Log Bucket", + "Section": "CCC.AuditLog.CN07 Enforce MFA Delete on Audit Log Bucket", "SubSection": "", - "SubSectionObjective": "Enable Multi-Factor Authentication (MFA) delete on the audit log bucket to\nprovide greater protection against accidental or malicious deletion of audit data.", + "SubSectionObjective": "Enable Multi-Factor Authentication (MFA) delete on the audit log bucket to provide greater protection against accidental or malicious deletion of audit data.", "Applicability": [ "tlp-red", "tlp-amber", "tlp-green" ], - "Recommendation": "Enable MFA Delete (or equivalent multi-factor authentication for delete operations)\non the audit log bucket.\n", + "Recommendation": "Enable MFA Delete (or equivalent multi-factor authentication for delete operations) on the audit log bucket. ", "SectionThreatMappings": [ { "ReferenceId": "CCC", @@ -449,20 +449,20 @@ ] }, { - "Id": "CCC.AuditLog.C08.TR01", - "Description": "When an attempt is made to delete data before the object\nlock period expires, then the deletion MUST be denied.", + "Id": "CCC.AuditLog.CN08.AR01", + "Description": "When an attempt is made to delete data before the object lock period expires, then the deletion MUST be denied.", "Attributes": [ { "FamilyName": "Availability", "FamilyDescription": "Controls designed to protected the availability of Audit Log data.", - "Section": "CCC.AuditLog.C08 Enable Object Lock On Audit Log Bucket", + "Section": "CCC.AuditLog.CN08 Enable Object Lock On Audit Log Bucket", "SubSection": "", - "SubSectionObjective": "Ensure that object log is enabled globally on all objects with the bucket.\nThe lock time MUST be configured to meet your organization, legal and compliance goals.\nDeletion attempts before the lock period MUST be denied.", + "SubSectionObjective": "Ensure that object log is enabled globally on all objects with the bucket. The lock time MUST be configured to meet your organization, legal and compliance goals. Deletion attempts before the lock period MUST be denied.", "Applicability": [ "tlp-red", "tlp-amber" ], - "Recommendation": "Configure object lock policy.\n", + "Recommendation": "Configure object lock policy. ", "SectionThreatMappings": [ { "ReferenceId": "CCC", @@ -493,20 +493,20 @@ ] }, { - "Id": "CCC.AuditLog.C09.TR01", + "Id": "CCC.AuditLog.CN09.AR01", "Description": "When restricted fields are accessed by unauthorized users, then those fields MUST remain masked.", "Attributes": [ { "FamilyName": "Confidentiality", "FamilyDescription": "Controls designed to protected the confidentiality of Audit Log data.", - "Section": "CCC.AuditLog.C09 Restrict Field And Log Type Access", + "Section": "CCC.AuditLog.CN09 Restrict Field And Log Type Access", "SubSection": "", - "SubSectionObjective": "Configure access to audit logs to follow the principle of least privilege in particular where technically\npossible limit the log fields users have access to to prevent accidental exposure to sensitive\ninformation such as PII.", + "SubSectionObjective": "Configure access to audit logs to follow the principle of least privilege in particular where technically possible limit the log fields users have access to to prevent accidental exposure to sensitive information such as PII.", "Applicability": [ "tlp-red", "tlp-amber" ], - "Recommendation": "Review field level access controls on audit data.\n", + "Recommendation": "Review field level access controls on audit data. ", "SectionThreatMappings": [ { "ReferenceId": "CCC", @@ -545,21 +545,21 @@ ] }, { - "Id": "CCC.AuditLog.C10.TR01", - "Description": "When audit log storage bucket's are created then, bucket's access control settings MUST explicitly deny\npublic read and write access.", + "Id": "CCC.AuditLog.CN10.AR01", + "Description": "When audit log storage bucket's are created then, bucket's access control settings MUST explicitly deny public read and write access.", "Attributes": [ { "FamilyName": "Confidentiality", "FamilyDescription": "Controls designed to protected the confidentiality of Audit Log data.", - "Section": "CCC.AuditLog.C10 Ensure Audit Bucket is Not Publicly Accessible", + "Section": "CCC.AuditLog.CN10 Ensure Audit Bucket is Not Publicly Accessible", "SubSection": "", - "SubSectionObjective": "Ensure that audit log storage buckets are not publicly accessible to prevent\nunauthorized exposure of sensitive log data.", + "SubSectionObjective": "Ensure that audit log storage buckets are not publicly accessible to prevent unauthorized exposure of sensitive log data.", "Applicability": [ "tlp-red", "tlp-amber", "tlp-green" ], - "Recommendation": "Configure bucket policies and access control lists (ACLs) to restrict public access.\nRegularly review bucket permissions to ensure no public access has been inadvertently granted.\n", + "Recommendation": "Configure bucket policies and access control lists (ACLs) to restrict public access. Regularly review bucket permissions to ensure no public access has been inadvertently granted. ", "SectionThreatMappings": [ { "ReferenceId": "CCC", @@ -593,21 +593,21 @@ ] }, { - "Id": "CCC.AuditLog.C10.TR02", - "Description": "When the URL of a audit log storage bucket's object is accessed publicly then,\nit should be denied by bucket policy.", + "Id": "CCC.AuditLog.CN10.AR02", + "Description": "When the URL of a audit log storage bucket's object is accessed publicly then, it should be denied by bucket policy.", "Attributes": [ { "FamilyName": "Confidentiality", "FamilyDescription": "Controls designed to protected the confidentiality of Audit Log data.", - "Section": "CCC.AuditLog.C10 Ensure Audit Bucket is Not Publicly Accessible", + "Section": "CCC.AuditLog.CN10 Ensure Audit Bucket is Not Publicly Accessible", "SubSection": "", - "SubSectionObjective": "Ensure that audit log storage buckets are not publicly accessible to prevent\nunauthorized exposure of sensitive log data.", + "SubSectionObjective": "Ensure that audit log storage buckets are not publicly accessible to prevent unauthorized exposure of sensitive log data.", "Applicability": [ "tlp-red", "tlp-amber", "tlp-green" ], - "Recommendation": "Configure bucket policies and access control lists (ACLs) to restrict public access.\nRegularly review bucket permissions to ensure no public access has been inadvertently granted.\n", + "Recommendation": "Configure bucket policies and access control lists (ACLs) to restrict public access. Regularly review bucket permissions to ensure no public access has been inadvertently granted. ", "SectionThreatMappings": [ { "ReferenceId": "CCC", @@ -642,15 +642,15 @@ ] }, { - "Id": "CCC.Build.C01.TR01", + "Id": "CCC.Build.CN01.AR01", "Description": "Attempt to initiate a build using an unauthorized build agent and verify that the build is rejected.", "Attributes": [ { "FamilyName": "Access Control", "FamilyDescription": "TODO: Describe this control family", - "Section": "CCC.Build.C01 Restrict Allowed Build Agents", + "Section": "CCC.Build.CN01 Restrict Allowed Build Agents", "SubSection": "", - "SubSectionObjective": "Ensure that builds are executed only on authorized build agents to maintain\ncontrol over the build environment and prevent unauthorized code execution.", + "SubSectionObjective": "Ensure that builds are executed only on authorized build agents to maintain control over the build environment and prevent unauthorized code execution.", "Applicability": [ "tlp-red", "tlp-amber" @@ -693,15 +693,15 @@ ] }, { - "Id": "CCC.Build.C02.TR01", - "Description": "Attempt to trigger a build from an unauthorized external service or\nrepository and verify that the build does not start.", + "Id": "CCC.Build.CN02.AR01", + "Description": "Attempt to trigger a build from an unauthorized external service or repository and verify that the build does not start.", "Attributes": [ { "FamilyName": "Access Control", "FamilyDescription": "TODO: Describe this control family", - "Section": "CCC.Build.C02 Restrict Allowed External Services for Build Triggers", + "Section": "CCC.Build.CN02 Restrict Allowed External Services for Build Triggers", "SubSection": "", - "SubSectionObjective": "Ensure that builds can only be triggered by authorized external services or\nrepositories to prevent unauthorized code execution or tampering.", + "SubSectionObjective": "Ensure that builds can only be triggered by authorized external services or repositories to prevent unauthorized code execution or tampering.", "Applicability": [ "tlp-red", "tlp-amber" @@ -740,15 +740,15 @@ ] }, { - "Id": "CCC.Build.C03.TR01", + "Id": "CCC.Build.CN03.AR01", "Description": "Attempt to access the build environment from an external network and verify that access is denied.", "Attributes": [ { "FamilyName": "Network Security", "FamilyDescription": "TODO: Describe this control family", - "Section": "CCC.Build.C03 Deny External Network Access for Build Environments", + "Section": "CCC.Build.CN03 Deny External Network Access for Build Environments", "SubSection": "", - "SubSectionObjective": "Ensure that build environments do not have external network access to\nprevent unauthorized external access and data exfiltration.", + "SubSectionObjective": "Ensure that build environments do not have external network access to prevent unauthorized external access and data exfiltration.", "Applicability": [ "tlp-red", "tlp-amber" @@ -785,15 +785,15 @@ ] }, { - "Id": "CCC.CntrReg.C01.TR01", - "Description": "Attempt to push an artifact with known vulnerabilities to the registry\nand observe if it is flagged or rejected by the vulnerability scanning process.", + "Id": "CCC.CntrReg.CN01.AR01", + "Description": "Attempt to push an artifact with known vulnerabilities to the registry and observe if it is flagged or rejected by the vulnerability scanning process.", "Attributes": [ { "FamilyName": "Risk Management", "FamilyDescription": "TODO: Describe this control family", - "Section": "CCC.CntrReg.C01 Implement Vulnerability Scanning for Artifacts", + "Section": "CCC.CntrReg.CN01 Implement Vulnerability Scanning for Artifacts", "SubSection": "", - "SubSectionObjective": "Ensure that container images and artifacts stored in the container registry are scanned for\nvulnerabilities to identify and remediate security issues before deployment.", + "SubSectionObjective": "Ensure that container images and artifacts stored in the container registry are scanned for vulnerabilities to identify and remediate security issues before deployment.", "Applicability": [ "tlp-red", "tlp-amber" @@ -830,59 +830,15 @@ ] }, { - "Id": "CCC.CntrReg.C02.TR01", - "Description": "Confirm that artifacts older than the specified retention period are automatically\ndeleted from the registry.", - "Attributes": [ - { - "FamilyName": "Data Management", - "FamilyDescription": "TODO: Describe this control family", - "Section": "CCC.CntrReg.C02 Implement Cleanup Policies for Artifacts", - "SubSection": "", - "SubSectionObjective": "Ensure that unused or outdated artifacts are cleaned up according to defined policies to\nmanage storage effectively and reduce security risks associated with outdated versions.", - "Applicability": [ - "tlp-red", - "tlp-amber" - ], - "Recommendation": "", - "SectionThreatMappings": [ - { - "ReferenceId": "CCC", - "Identifiers": [ - "CCC.TH14" - ] - } - ], - "SectionGuidelineMappings": [ - { - "ReferenceId": "NIST-CSF", - "Identifiers": [ - "PR.IP-6" - ] - }, - { - "ReferenceId": "NIST_800_53", - "Identifiers": [ - "SI-12" - ] - } - ] - } - ], - "Checks": [ - "ecr_repositories_lifecycle_policy_enabled", - "s3_bucket_lifecycle_enabled" - ] - }, - { - "Id": "CCC.DataWar.C01.TR01", - "Description": "Attempt to access underlying database tables directly without\nusing managed views and verify that access is denied.", + "Id": "CCC.DataWar.CN01.AR01", + "Description": "Attempt to access underlying database tables directly without using managed views and verify that access is denied.", "Attributes": [ { "FamilyName": "Data", "FamilyDescription": "TODO: Describe this control family", - "Section": "CCC.DataWar.C01 Enforce Use of Managed Views for Data Access", + "Section": "CCC.DataWar.CN01 Enforce Use of Managed Views for Data Access", "SubSection": "", - "SubSectionObjective": "Ensure that data access is provided through managed views, restricting users\nfrom accessing underlying tables directly and enforcing consistent security policies.", + "SubSectionObjective": "Ensure that data access is provided through managed views, restricting users from accessing underlying tables directly and enforcing consistent security policies.", "Applicability": [ "tlp-red", "tlp-amber" @@ -916,15 +872,15 @@ "Checks": [] }, { - "Id": "CCC.DataWar.C02.TR01", - "Description": "Attempt to query sensitive columns without the necessary permissions and\nverify that access is denied or data is masked.", + "Id": "CCC.DataWar.CN02.AR01", + "Description": "Attempt to query sensitive columns without the necessary permissions and verify that access is denied or data is masked.", "Attributes": [ { "FamilyName": "Data", "FamilyDescription": "TODO: Describe this control family", - "Section": "CCC.DataWar.C02 Enforce Column-Level Security Policies", + "Section": "CCC.DataWar.CN02 Enforce Column-Level Security Policies", "SubSection": "", - "SubSectionObjective": "Ensure that access to sensitive data columns is restricted based on user roles,\npreventing unauthorized access to sensitive information.", + "SubSectionObjective": "Ensure that access to sensitive data columns is restricted based on user roles, preventing unauthorized access to sensitive information.", "Applicability": [ "tlp-red", "tlp-amber" @@ -958,15 +914,15 @@ "Checks": [] }, { - "Id": "CCC.DataWar.C03.TR01", - "Description": "Attempt to query data rows that the user should not have access to and verify\nthat access is denied or data is not returned.", + "Id": "CCC.DataWar.CN03.AR01", + "Description": "Attempt to query data rows that the user should not have access to and verify that access is denied or data is not returned.", "Attributes": [ { "FamilyName": "Data", "FamilyDescription": "TODO: Describe this control family", - "Section": "CCC.DataWar.C03 Enforce Row-Level Security Policies", + "Section": "CCC.DataWar.CN03 Enforce Row-Level Security Policies", "SubSection": "", - "SubSectionObjective": "Ensure that access to data rows is restricted based on user roles or attributes,\npreventing unauthorized access to specific subsets of data.", + "SubSectionObjective": "Ensure that access to data rows is restricted based on user roles or attributes, preventing unauthorized access to specific subsets of data.", "Applicability": [ "tlp-red", "tlp-amber" @@ -1000,743 +956,13 @@ "Checks": [] }, { - "Id": "CCC.GenAI.C01.TR01", - "Description": "Untrusted input such as user queries, RAG data or tool output\nMUST be validated before it is passed to a GenAI model.", - "Attributes": [ - { - "FamilyName": "Data", - "FamilyDescription": "The Data control family ensures the confidentiality, integrity,\navailability, and sovereignty of data across its lifecycle.\nThese controls govern how data is transmitted, stored,\nreplicated, and protected from unauthorized access, tampering,\nor exposure beyond defined trust perimeters.\n", - "Section": "CCC.GenAI.C01 Model Input Filtering and Sanitisation", - "SubSection": "", - "SubSectionObjective": "Inspect and validate input before it is passed to a GenAI\nmodel in order to filter or sanitise adversarial queries\nand prevent sensitive data leakage.", - "Applicability": [ - "tlp-clear", - "tlp-green", - "tlp-amber", - "tlp-red" - ], - "Recommendation": "", - "SectionThreatMappings": [ - { - "ReferenceId": "CCC", - "Identifiers": [ - "CCC.GenAI.TH01", - "CCC.GenAI.TH03" - ] - } - ], - "SectionGuidelineMappings": [ - { - "ReferenceId": "FINOS-AIGF", - "Identifiers": [ - "AIR-PREV-003", - "AIR-PREV-017", - "AIR-PREV-002", - "AIR-DET-001" - ] - }, - { - "ReferenceId": "SAIF", - "Identifiers": [ - "Input Validation and Sanitization" - ] - }, - { - "ReferenceId": "MITRE-ATLAS", - "Identifiers": [ - "AML.M0020", - "AML.M0021", - "AML.M0015" - ] - } - ] - } - ], - "Checks": [ - "bedrock_guardrail_prompt_attack_filter_enabled", - "bedrock_guardrail_sensitive_information_filter_enabled", - "bedrock_model_invocation_logging_enabled", - "bedrock_model_invocation_logs_encryption_enabled", - "bedrock_agent_guardrail_enabled" - ] - }, - { - "Id": "CCC.GenAI.C01.TR02", - "Description": "If malicious patterns such as prompt injection or sensitive\ndata are detected during input validation, the input MUST\nbe blocked or sanitised.", - "Attributes": [ - { - "FamilyName": "Data", - "FamilyDescription": "The Data control family ensures the confidentiality, integrity,\navailability, and sovereignty of data across its lifecycle.\nThese controls govern how data is transmitted, stored,\nreplicated, and protected from unauthorized access, tampering,\nor exposure beyond defined trust perimeters.\n", - "Section": "CCC.GenAI.C01 Model Input Filtering and Sanitisation", - "SubSection": "", - "SubSectionObjective": "Inspect and validate input before it is passed to a GenAI\nmodel in order to filter or sanitise adversarial queries\nand prevent sensitive data leakage.", - "Applicability": [ - "tlp-clear", - "tlp-green", - "tlp-amber", - "tlp-red" - ], - "Recommendation": "", - "SectionThreatMappings": [ - { - "ReferenceId": "CCC", - "Identifiers": [ - "CCC.GenAI.TH01", - "CCC.GenAI.TH03" - ] - } - ], - "SectionGuidelineMappings": [ - { - "ReferenceId": "FINOS-AIGF", - "Identifiers": [ - "AIR-PREV-003", - "AIR-PREV-017", - "AIR-PREV-002", - "AIR-DET-001" - ] - }, - { - "ReferenceId": "SAIF", - "Identifiers": [ - "Input Validation and Sanitization" - ] - }, - { - "ReferenceId": "MITRE-ATLAS", - "Identifiers": [ - "AML.M0020", - "AML.M0021", - "AML.M0015" - ] - } - ] - } - ], - "Checks": [ - "bedrock_guardrail_prompt_attack_filter_enabled", - "bedrock_guardrail_sensitive_information_filter_enabled" - ] - }, - { - "Id": "CCC.GenAI.C02.TR01", - "Description": "GenAI model output MUST be validated for format conformance,\nmalicious patterns, sensitive data and inapropriate content\nbefore being passed to users, application or plugins.", - "Attributes": [ - { - "FamilyName": "Data", - "FamilyDescription": "The Data control family ensures the confidentiality, integrity,\navailability, and sovereignty of data across its lifecycle.\nThese controls govern how data is transmitted, stored,\nreplicated, and protected from unauthorized access, tampering,\nor exposure beyond defined trust perimeters.\n", - "Section": "CCC.GenAI.C02 Model Output Filtering and Sanitisation", - "SubSection": "", - "SubSectionObjective": "Inspect and validate GenAI model output before passing it to\nusers, applications or plugins in order to filter or sanitise\ninsecure or unreliable output and prevent sensitive data leakage.", - "Applicability": [ - "tlp-clear", - "tlp-green", - "tlp-amber", - "tlp-red" - ], - "Recommendation": "", - "SectionThreatMappings": [ - { - "ReferenceId": "CCC", - "Identifiers": [ - "CCC.GenAI.TH01", - "CCC.GenAI.TH03", - "CCC.GenAI.TH04", - "CCC.GenAI.TH05", - "CCC.GenAI.TH06" - ] - } - ], - "SectionGuidelineMappings": [ - { - "ReferenceId": "FINOS-AIGF", - "Identifiers": [ - "AIR-PREV-003", - "AIR-PREV-017", - "AIR-PREV-002", - "AIR-DET-001" - ] - }, - { - "ReferenceId": "SAIF", - "Identifiers": [ - "Output Validation and Sanitization" - ] - }, - { - "ReferenceId": "MITRE-ATLAS", - "Identifiers": [ - "AML.M0020", - "AML.M0002" - ] - } - ] - } - ], - "Checks": [ - "bedrock_guardrail_sensitive_information_filter_enabled", - "bedrock_guardrail_prompt_attack_filter_enabled" - ] - }, - { - "Id": "CCC.GenAI.C02.TR02", - "Description": "In the event of policy violations, the AI-generated content MUST\nbe redacted, encoded or rejected.", - "Attributes": [ - { - "FamilyName": "Data", - "FamilyDescription": "The Data control family ensures the confidentiality, integrity,\navailability, and sovereignty of data across its lifecycle.\nThese controls govern how data is transmitted, stored,\nreplicated, and protected from unauthorized access, tampering,\nor exposure beyond defined trust perimeters.\n", - "Section": "CCC.GenAI.C02 Model Output Filtering and Sanitisation", - "SubSection": "", - "SubSectionObjective": "Inspect and validate GenAI model output before passing it to\nusers, applications or plugins in order to filter or sanitise\ninsecure or unreliable output and prevent sensitive data leakage.", - "Applicability": [ - "tlp-clear", - "tlp-green", - "tlp-amber", - "tlp-red" - ], - "Recommendation": "", - "SectionThreatMappings": [ - { - "ReferenceId": "CCC", - "Identifiers": [ - "CCC.GenAI.TH01", - "CCC.GenAI.TH03", - "CCC.GenAI.TH04", - "CCC.GenAI.TH05", - "CCC.GenAI.TH06" - ] - } - ], - "SectionGuidelineMappings": [ - { - "ReferenceId": "FINOS-AIGF", - "Identifiers": [ - "AIR-PREV-003", - "AIR-PREV-017", - "AIR-PREV-002", - "AIR-DET-001" - ] - }, - { - "ReferenceId": "SAIF", - "Identifiers": [ - "Output Validation and Sanitization" - ] - }, - { - "ReferenceId": "MITRE-ATLAS", - "Identifiers": [ - "AML.M0020", - "AML.M0002" - ] - } - ] - } - ], - "Checks": [ - "bedrock_guardrail_prompt_attack_filter_enabled", - "bedrock_guardrail_sensitive_information_filter_enabled", - "bedrock_model_invocation_logging_enabled", - "bedrock_model_invocation_logs_encryption_enabled", - "bedrock_agent_guardrail_enabled" - ] - }, - { - "Id": "CCC.GenAI.C03.TR01", - "Description": "When data is designated for model training or RAG ingestion, then its\nsource MUST be explicitly approved and its provenance documented.", - "Attributes": [ - { - "FamilyName": "Data", - "FamilyDescription": "The Data control family ensures the confidentiality, integrity,\navailability, and sovereignty of data across its lifecycle.\nThese controls govern how data is transmitted, stored,\nreplicated, and protected from unauthorized access, tampering,\nor exposure beyond defined trust perimeters.\n", - "Section": "CCC.GenAI.C03 Data Provenance and Source Vetting", - "SubSection": "", - "SubSectionObjective": "Ensure that all data for training, fine-tuning or RAG comes\nfrom trusted, approved sources and is authorised for the\nintended purposes in order to prevent the initial introduction\nof malicious content or leaked sensitive data.", - "Applicability": [ - "tlp-clear", - "tlp-green", - "tlp-amber", - "tlp-red" - ], - "Recommendation": "", - "SectionThreatMappings": [ - { - "ReferenceId": "CCC", - "Identifiers": [ - "CCC.GenAI.TH02", - "CCC.GenAI.TH03" - ] - } - ], - "SectionGuidelineMappings": [ - { - "ReferenceId": "FINOS-AIGF", - "Identifiers": [ - "AIR-PREV-006" - ] - }, - { - "ReferenceId": "SAIF", - "Identifiers": [ - "Training Data Management" - ] - }, - { - "ReferenceId": "MITRE-ATLAS", - "Identifiers": [ - "AML.M0025" - ] - } - ] - } - ], - "Checks": [] - }, - { - "Id": "CCC.GenAI.C03.TR02", - "Description": "Data from unvetted sources MUST NOT be used in production systems.", - "Attributes": [ - { - "FamilyName": "Data", - "FamilyDescription": "The Data control family ensures the confidentiality, integrity,\navailability, and sovereignty of data across its lifecycle.\nThese controls govern how data is transmitted, stored,\nreplicated, and protected from unauthorized access, tampering,\nor exposure beyond defined trust perimeters.\n", - "Section": "CCC.GenAI.C03 Data Provenance and Source Vetting", - "SubSection": "", - "SubSectionObjective": "Ensure that all data for training, fine-tuning or RAG comes\nfrom trusted, approved sources and is authorised for the\nintended purposes in order to prevent the initial introduction\nof malicious content or leaked sensitive data.", - "Applicability": [ - "tlp-clear", - "tlp-green", - "tlp-amber", - "tlp-red" - ], - "Recommendation": "", - "SectionThreatMappings": [ - { - "ReferenceId": "CCC", - "Identifiers": [ - "CCC.GenAI.TH02", - "CCC.GenAI.TH03" - ] - } - ], - "SectionGuidelineMappings": [ - { - "ReferenceId": "FINOS-AIGF", - "Identifiers": [ - "AIR-PREV-006" - ] - }, - { - "ReferenceId": "SAIF", - "Identifiers": [ - "Training Data Management" - ] - }, - { - "ReferenceId": "MITRE-ATLAS", - "Identifiers": [ - "AML.M0025" - ] - } - ] - } - ], - "Checks": [ - "vpc_endpoint_services_allowed_principals_trust_boundaries", - "vpc_endpoint_connections_trust_boundaries", - "s3_bucket_cross_account_access", - "s3_bucket_cross_region_replication", - "s3_bucket_public_access", - "s3_bucket_public_list_acl", - "s3_bucket_public_write_acl", - "s3_bucket_secure_transport_policy", - "s3_bucket_kms_encryption", - "s3_account_level_public_access_blocks", - "s3_bucket_level_public_access_block", - "s3_access_point_public_access_block" - ] - }, - { - "Id": "CCC.GenAI.C04.TR01", - "Description": "When data is ingested for training, fine-tuning or conversion\nto vector embeddings, it MUST be validated for sensitive\ninformation or malicious content.", - "Attributes": [ - { - "FamilyName": "Data", - "FamilyDescription": "The Data control family ensures the confidentiality, integrity,\navailability, and sovereignty of data across its lifecycle.\nThese controls govern how data is transmitted, stored,\nreplicated, and protected from unauthorized access, tampering,\nor exposure beyond defined trust perimeters.\n", - "Section": "CCC.GenAI.C04 Sanitisation of Ingested Data", - "SubSection": "", - "SubSectionObjective": "Validate and sanitise all data ingested by GenAI systems\nfrom extenal sources or internal knowledge bases, whether\nfor training, conversion to vector embeddings, or real-time\nretireval, in order to remove or redact poisoned or sensitive\ndata before further processing.", - "Applicability": [ - "tlp-clear", - "tlp-green", - "tlp-amber", - "tlp-red" - ], - "Recommendation": "", - "SectionThreatMappings": [ - { - "ReferenceId": "CCC", - "Identifiers": [ - "CCC.GenAI.TH02", - "CCC.GenAI.TH03" - ] - } - ], - "SectionGuidelineMappings": [ - { - "ReferenceId": "FINOS-AIGF", - "Identifiers": [ - "AIR-PREV-002" - ] - }, - { - "ReferenceId": "SAIF", - "Identifiers": [ - "Training Data Sanitization" - ] - }, - { - "ReferenceId": "MITRE-ATLAS", - "Identifiers": [ - "AML.M0007" - ] - } - ] - } - ], - "Checks": [ - "cloudformation_stack_outputs_find_secrets", - "ec2_instance_secrets_user_data", - "ec2_launch_template_no_secrets", - "ssm_document_secrets", - "cloudwatch_log_group_no_secrets_in_logs", - "awslambda_function_no_secrets_in_variables", - "awslambda_function_no_secrets_in_code" - ] - }, - { - "Id": "CCC.GenAI.C04.TR02", - "Description": "If sensitive data or malicious content is detected, it must\nbe rejected, redacted or flagged for manual review.", - "Attributes": [ - { - "FamilyName": "Data", - "FamilyDescription": "The Data control family ensures the confidentiality, integrity,\navailability, and sovereignty of data across its lifecycle.\nThese controls govern how data is transmitted, stored,\nreplicated, and protected from unauthorized access, tampering,\nor exposure beyond defined trust perimeters.\n", - "Section": "CCC.GenAI.C04 Sanitisation of Ingested Data", - "SubSection": "", - "SubSectionObjective": "Validate and sanitise all data ingested by GenAI systems\nfrom extenal sources or internal knowledge bases, whether\nfor training, conversion to vector embeddings, or real-time\nretireval, in order to remove or redact poisoned or sensitive\ndata before further processing.", - "Applicability": [ - "tlp-clear", - "tlp-green", - "tlp-amber", - "tlp-red" - ], - "Recommendation": "", - "SectionThreatMappings": [ - { - "ReferenceId": "CCC", - "Identifiers": [ - "CCC.GenAI.TH02", - "CCC.GenAI.TH03" - ] - } - ], - "SectionGuidelineMappings": [ - { - "ReferenceId": "FINOS-AIGF", - "Identifiers": [ - "AIR-PREV-002" - ] - }, - { - "ReferenceId": "SAIF", - "Identifiers": [ - "Training Data Sanitization" - ] - }, - { - "ReferenceId": "MITRE-ATLAS", - "Identifiers": [ - "AML.M0007" - ] - } - ] - } - ], - "Checks": [ - "bedrock_guardrail_prompt_attack_filter_enabled", - "bedrock_guardrail_sensitive_information_filter_enabled", - "bedrock_agent_guardrail_enabled" - ] - }, - { - "Id": "CCC.GenAI.C05.TR01", - "Description": "When a RAG-enabled system generates a response containing information\nretrieved from its knowledge base, then the response MUST include a\nverifiable citation that links back to the specific source document.", - "Attributes": [ - { - "FamilyName": "Data", - "FamilyDescription": "The Data control family ensures the confidentiality, integrity,\navailability, and sovereignty of data across its lifecycle.\nThese controls govern how data is transmitted, stored,\nreplicated, and protected from unauthorized access, tampering,\nor exposure beyond defined trust perimeters.\n", - "Section": "CCC.GenAI.C05 Citations and Source Traceability", - "SubSection": "", - "SubSectionObjective": "Require the GenAI system to provide citations or direct links\nback to the source documents used to generate a response, in\nto enhance the transparency, trustworthiness, and verifiability\nof AI-generated content.", - "Applicability": [ - "tlp-clear", - "tlp-green", - "tlp-amber", - "tlp-red" - ], - "Recommendation": "", - "SectionThreatMappings": [ - { - "ReferenceId": "CCC", - "Identifiers": [ - "CCC.GenAI.TH09", - "CCC.GenAI.TH04" - ] - } - ], - "SectionGuidelineMappings": [ - { - "ReferenceId": "FINOS-AIGF", - "Identifiers": [ - "AIR-DET-013" - ] - } - ] - } - ], - "Checks": [ - "cloudtrail_multi_region_enabled", - "cloudtrail_cloudwatch_logging_enabled", - "cloudtrail_kms_encryption_enabled", - "cloudtrail_logs_s3_bucket_is_not_publicly_accessible", - "cloudtrail_s3_dataevents_read_enabled", - "cloudtrail_s3_dataevents_write_enabled", - "cloudtrail_log_file_validation_enabled" - ] - }, - { - "Id": "CCC.GenAI.C06.TR01", - "Description": "When an LLM invokes an external tool (e.g., an API, a plugin),\nthen the tool MUST operate with the least privileges required\nfor performing its intended functionality.", - "Attributes": [ - { - "FamilyName": "Identity and Access Management", - "FamilyDescription": "The Identity and Access Management control family ensures\nthat only trusted and authenticated entities can access\nresources. These controls establish strong authentication,\nenforce multi-factor verification, and restrict access to\napproved sources to prevent unauthorized use or data exfiltration.\n", - "Section": "CCC.GenAI.C06 Least Privilege for Plugins", - "SubSection": "", - "SubSectionObjective": "Restricts the permissions of any external tools the GenAI system\ncan call to limit the potential damage if an agent is coerced\nto perform unintended actions or vulnerabilities in the tools\nare exploited.", - "Applicability": [ - "tlp-clear", - "tlp-green", - "tlp-amber", - "tlp-red" - ], - "Recommendation": "", - "SectionThreatMappings": [ - { - "ReferenceId": "CCC", - "Identifiers": [ - "CCC.GenAI.TH07", - "CCC.GenAI.TH06" - ] - } - ], - "SectionGuidelineMappings": [ - { - "ReferenceId": "SAIF", - "Identifiers": [ - "Agent Permissions" - ] - } - ] - } - ], - "Checks": [ - "apigateway_restapi_authorizers_enabled", - "apigatewayv2_api_authorizers_enabled", - "apigateway_restapi_public", - "apigateway_restapi_public_with_authorizer", - "awslambda_function_url_public", - "awslambda_function_not_publicly_accessible", - "iam_policy_allows_privilege_escalation", - "iam_inline_policy_allows_privilege_escalation", - "iam_policy_no_full_access_to_cloudtrail", - "iam_policy_no_full_access_to_kms", - "iam_inline_policy_no_full_access_to_cloudtrail", - "iam_inline_policy_no_full_access_to_kms", - "iam_group_administrator_access_policy", - "iam_user_administrator_access_policy", - "iam_role_administratoraccess_policy" - ] - }, - { - "Id": "CCC.GenAI.C07.TR01", - "Description": "When an application makes an API call to a foundational model in a\nproduction environment, then it MUST specify an explicit version\nidentifier.", - "Attributes": [ - { - "FamilyName": "Configuration Management", - "FamilyDescription": "The Configuration Management control family involves establishing,\nmaintaining and monitoring the configuration of the service and\nrelated applications and infrastructure to ensure consistency,\nsecure defaults and compliance.\n", - "Section": "CCC.GenAI.C07 Model Version Pinning", - "SubSection": "", - "SubSectionObjective": "Mandate that applications are locked (\"pinned\") to a specific,\ntested version of a foundational model to prevent unexpected\nbehaviour changes introduced by provider-side updates.", - "Applicability": [ - "tlp-clear", - "tlp-green", - "tlp-amber", - "tlp-red" - ], - "Recommendation": "", - "SectionThreatMappings": [ - { - "ReferenceId": "CCC", - "Identifiers": [ - "CCC.GenAI.TH10" - ] - } - ], - "SectionGuidelineMappings": [ - { - "ReferenceId": "FINOS-AIGF", - "Identifiers": [ - "AIR-PREV-010" - ] - } - ] - } - ], - "Checks": [] - }, - { - "Id": "CCC.GenAI.C08.TR01", - "Description": "When a new AI model is considered for production deployment, it\nMUST undergo a formal red teaming and quality assurance review.", - "Attributes": [ - { - "FamilyName": "Model Assurance and Evaluation", - "FamilyDescription": "The Model Assurance and Evaluation control family encompasses\nthe proactiveand continuous processes of testing and validating\nthe AI model's behavior to ensure it aligns with safety, ethical,\nand quality standards.\n", - "Section": "CCC.GenAI.C08 Quality Control and Red Teaming", - "SubSection": "", - "SubSectionObjective": "Establish a formal program for quality evaluation and adversarial\ntesting (red teaming) to ensure GenAI system meet all business,\nquality, security and compliance requirements before getting deployed\ninto production environments.", - "Applicability": [ - "tlp-clear", - "tlp-green", - "tlp-amber", - "tlp-red" - ], - "Recommendation": "", - "SectionThreatMappings": [ - { - "ReferenceId": "CCC", - "Identifiers": [ - "CCC.GenAI.TH01", - "CCC.GenAI.TH02", - "CCC.GenAI.TH04", - "CCC.GenAI.TH08", - "CCC.GenAI.TH10" - ] - } - ], - "SectionGuidelineMappings": [ - { - "ReferenceId": "FINOS-AIGF", - "Identifiers": [ - "AIR-PREV-005" - ] - }, - { - "ReferenceId": "SAIF", - "Identifiers": [ - "Adversarial Training and Testing", - "Red Teaming", - "Product Governance" - ] - }, - { - "ReferenceId": "MITRE-ATLAS", - "Identifiers": [ - "AML.M0008" - ] - } - ] - } - ], - "Checks": [ - "bedrock_guardrail_prompt_attack_filter_enabled", - "bedrock_guardrail_sensitive_information_filter_enabled", - "bedrock_agent_guardrail_enabled", - "bedrock_model_invocation_logging_enabled", - "bedrock_model_invocation_logs_encryption_enabled", - "bedrock_api_key_no_administrative_privileges", - "bedrock_api_key_no_long_term_credentials" - ] - }, - { - "Id": "CCC.GenAI.C08.TR02", - "Description": "If model quality review or red teaming identifies an issue that exceeds\nthe organization's risk tolerance, the model MUST NOT be deployed until\nthe issue is remediated.", - "Attributes": [ - { - "FamilyName": "Model Assurance and Evaluation", - "FamilyDescription": "The Model Assurance and Evaluation control family encompasses\nthe proactiveand continuous processes of testing and validating\nthe AI model's behavior to ensure it aligns with safety, ethical,\nand quality standards.\n", - "Section": "CCC.GenAI.C08 Quality Control and Red Teaming", - "SubSection": "", - "SubSectionObjective": "Establish a formal program for quality evaluation and adversarial\ntesting (red teaming) to ensure GenAI system meet all business,\nquality, security and compliance requirements before getting deployed\ninto production environments.", - "Applicability": [ - "tlp-clear", - "tlp-green", - "tlp-amber", - "tlp-red" - ], - "Recommendation": "", - "SectionThreatMappings": [ - { - "ReferenceId": "CCC", - "Identifiers": [ - "CCC.GenAI.TH01", - "CCC.GenAI.TH02", - "CCC.GenAI.TH04", - "CCC.GenAI.TH08", - "CCC.GenAI.TH10" - ] - } - ], - "SectionGuidelineMappings": [ - { - "ReferenceId": "FINOS-AIGF", - "Identifiers": [ - "AIR-PREV-005" - ] - }, - { - "ReferenceId": "SAIF", - "Identifiers": [ - "Adversarial Training and Testing", - "Red Teaming", - "Product Governance" - ] - }, - { - "ReferenceId": "MITRE-ATLAS", - "Identifiers": [ - "AML.M0008" - ] - } - ] - } - ], - "Checks": [ - "bedrock_guardrail_prompt_attack_filter_enabled", - "bedrock_guardrail_sensitive_information_filter_enabled", - "bedrock_model_invocation_logging_enabled", - "bedrock_model_invocation_logs_encryption_enabled", - "bedrock_agent_guardrail_enabled", - "bedrock_api_key_no_administrative_privileges", - "bedrock_api_key_no_long_term_credentials" - ] - }, - { - "Id": "CCC.KeyMgmt.C01.TR01", - "Description": "When a key version is scheduled for deletion or disabled, an\nalert MUST be generated within five minutes.", + "Id": "CCC.KeyMgmt.CN01.AR01", + "Description": "When a key version is scheduled for deletion or disabled, an alert MUST be generated within five minutes.", "Attributes": [ { "FamilyName": "Logging and Metrics Publication", "FamilyDescription": "Controls that collect, alert, and retain key-management events.", - "Section": "CCC.KeyMgmt.C01 Alert on Key-version Changes", + "Section": "CCC.KeyMgmt.CN01 Alert on Key-version Changes", "SubSection": "", "SubSectionObjective": "Generate near-real-time alerts when a KMS key version is disabled or scheduled for deletion, enabling rapid investigation and recovery.", "Applicability": [ @@ -1773,13 +999,13 @@ ] }, { - "Id": "CCC.KeyMgmt.C02.TR01", - "Description": "When IAM roles and key policies are reviewed, Decrypt permission\nMUST be granted exclusively to documented authorised principals.", + "Id": "CCC.KeyMgmt.CN02.AR01", + "Description": "When IAM roles and key policies are reviewed, Decrypt permission MUST be granted exclusively to documented authorised principals.", "Attributes": [ { "FamilyName": "Identity and Access Management", "FamilyDescription": "Controls that enforce least-privilege use of KMS operations.", - "Section": "CCC.KeyMgmt.C02 Limit Decrypt Permissions", + "Section": "CCC.KeyMgmt.CN02 Limit Decrypt Permissions", "SubSection": "", "SubSectionObjective": "Restrict the Decrypt operation to authorised principals only, applying the principle of least privilege to protect sensitive data.", "Applicability": [ @@ -1819,13 +1045,13 @@ ] }, { - "Id": "CCC.KeyMgmt.C03.TR01", - "Description": "When rotation settings are examined, rotation MUST be enabled with\nan interval not exceeding 365 days.", + "Id": "CCC.KeyMgmt.CN03.AR01", + "Description": "When rotation settings are examined, rotation MUST be enabled with an interval not exceeding 365 days.", "Attributes": [ { "FamilyName": "Key Lifecycle Management", "FamilyDescription": "Controls that govern creation, rotation, import, and retirement of cryptographic keys.", - "Section": "CCC.KeyMgmt.C03 Enforce Automatic Rotation", + "Section": "CCC.KeyMgmt.CN03 Enforce Automatic Rotation", "SubSection": "", "SubSectionObjective": "Ensure symmetric keys rotate automatically within policy intervals to reduce exposure of key material.", "Applicability": [ @@ -1861,13 +1087,13 @@ ] }, { - "Id": "CCC.KeyMgmt.C04.TR01", - "Description": "When a key import request is processed, the key MUST use an\napproved algorithm (RSA-2048+, EC-P256+) and originate from a\ncertified HSM.", + "Id": "CCC.KeyMgmt.CN04.AR01", + "Description": "When a key import request is processed, the key MUST use an approved algorithm (RSA-2048+, EC-P256+) and originate from a certified HSM.", "Attributes": [ { "FamilyName": "Key Lifecycle Management", "FamilyDescription": "Controls that govern creation, rotation, import, and retirement of cryptographic keys.", - "Section": "CCC.KeyMgmt.C04 Validate Imported Keys", + "Section": "CCC.KeyMgmt.CN04 Validate Imported Keys", "SubSection": "", "SubSectionObjective": "Accept only externally generated keys that meet approved cryptographic strength and provenance requirements.", "Applicability": [ @@ -1906,13 +1132,13 @@ ] }, { - "Id": "CCC.LB.C01.TR01", - "Description": "When a single client sends more than 2000 requests within any\n5-minute sliding window, the load balancer MUST throttle all\nsubsequent requests from that client for at least 60 seconds.", + "Id": "CCC.LB.CN01.AR01", + "Description": "When a single client sends more than 2000 requests within any 5-minute sliding window, the load balancer MUST throttle all subsequent requests from that client for at least 60 seconds.", "Attributes": [ { "FamilyName": "Logging & Monitoring", - "FamilyDescription": "Controls that detect anomalous traffic and record load-balancer activity.\n", - "Section": "CCC.LB.C01 Enforce and Detect Rate Limiting", + "FamilyDescription": "Controls that detect anomalous traffic and record load-balancer activity. ", + "Section": "CCC.LB.CN01 Enforce and Detect Rate Limiting", "SubSection": "", "SubSectionObjective": "Detect and throttle malicious or excessive requests to prevent downstream resource exhaustion and brute-force activity.", "Applicability": [ @@ -1920,7 +1146,7 @@ "tlp-amber", "tlp-red" ], - "Recommendation": "Implement per-IP token-bucket limits with and verify via\nsynthetic traffic tests.\n", + "Recommendation": "Implement per-IP token-bucket limits with and verify via synthetic traffic tests. ", "SectionThreatMappings": [ { "ReferenceId": "LB", @@ -1957,13 +1183,13 @@ ] }, { - "Id": "CCC.LB.C01.TR02", - "Description": "When throttling is invoked, the load balancer MUST\nrecord the event in the access log within 5 minutes\nfor alerting and trend analysis.", + "Id": "CCC.LB.CN01.AR02", + "Description": "When throttling is invoked, the load balancer MUST record the event in the access log within 5 minutes for alerting and trend analysis.", "Attributes": [ { "FamilyName": "Logging & Monitoring", - "FamilyDescription": "Controls that detect anomalous traffic and record load-balancer activity.\n", - "Section": "CCC.LB.C01 Enforce and Detect Rate Limiting", + "FamilyDescription": "Controls that detect anomalous traffic and record load-balancer activity. ", + "Section": "CCC.LB.CN01 Enforce and Detect Rate Limiting", "SubSection": "", "SubSectionObjective": "Detect and throttle malicious or excessive requests to prevent downstream resource exhaustion and brute-force activity.", "Applicability": [ @@ -1971,7 +1197,7 @@ "tlp-amber", "tlp-red" ], - "Recommendation": "Enable access logging and configure metric filters\non HTTP 429 counts to trigger alerts.\n", + "Recommendation": "Enable access logging and configure metric filters on HTTP 429 counts to trigger alerts. ", "SectionThreatMappings": [ { "ReferenceId": "LB", @@ -2008,21 +1234,21 @@ ] }, { - "Id": "CCC.LB.C06.TR01", - "Description": "When more than 10 percent of targets change from healthy to\nunhealthy within five minutes, an alert MUST be issued.", + "Id": "CCC.LB.CN06.AR01", + "Description": "When more than 10 percent of targets change from healthy to unhealthy within five minutes, an alert MUST be issued.", "Attributes": [ { "FamilyName": "Logging & Monitoring", - "FamilyDescription": "Controls that detect anomalous traffic and record load-balancer activity.\n", - "Section": "CCC.LB.C06 Secure Health-Check Telemetry", + "FamilyDescription": "Controls that detect anomalous traffic and record load-balancer activity. ", + "Section": "CCC.LB.CN06 Secure Health-Check Telemetry", "SubSection": "", - "SubSectionObjective": "Monitor health-check endpoints for tampering and alert on\nabnormal status changes.", + "SubSectionObjective": "Monitor health-check endpoints for tampering and alert on abnormal status changes.", "Applicability": [ "tlp-green", "tlp-amber", "tlp-red" ], - "Recommendation": "Instrument metrics for health check results and target\nremoval events. Configure monitoring alarms to alert\non abnormal spikes in unhealthy targets.\n", + "Recommendation": "Instrument metrics for health check results and target removal events. Configure monitoring alarms to alert on abnormal spikes in unhealthy targets. ", "SectionThreatMappings": [ { "ReferenceId": "LB", @@ -2056,21 +1282,21 @@ ] }, { - "Id": "CCC.LB.C04.TR01", - "Description": "When routing weights change, the request MUST originate\nfrom an explicitly defined and trusted identity and MUST\nbe logged.", + "Id": "CCC.LB.CN04.AR01", + "Description": "When routing weights change, the request MUST originate from an explicitly defined and trusted identity and MUST be logged.", "Attributes": [ { "FamilyName": "Identity and Access Management", - "FamilyDescription": "Controls that restrict who can change or query load-balancer resources.\n", - "Section": "CCC.LB.C04 Enforce Distribution Policies", + "FamilyDescription": "Controls that restrict who can change or query load-balancer resources. ", + "Section": "CCC.LB.CN04 Enforce Distribution Policies", "SubSection": "", - "SubSectionObjective": "Ensure traffic-splitting weights and algorithms are modified\nonly by trusted identities.", + "SubSectionObjective": "Ensure traffic-splitting weights and algorithms are modified only by trusted identities.", "Applicability": [ "tlp-green", "tlp-amber", "tlp-red" ], - "Recommendation": "Define a list of trusted principals allowed to modify\nrouting configurations. Enforce via conditional access\npolicies, and log changes using audit logging.\n", + "Recommendation": "Define a list of trusted principals allowed to modify routing configurations. Enforce via conditional access policies, and log changes using audit logging. ", "SectionThreatMappings": [ { "ReferenceId": "LB", @@ -2105,15 +1331,15 @@ ] }, { - "Id": "CCC.LB.C05.TR01", - "Description": "When stickiness is enabled, session cookies MUST expire\nwithin 30 minutes of inactivity.", + "Id": "CCC.LB.CN05.AR01", + "Description": "When stickiness is enabled, session cookies MUST expire within 30 minutes of inactivity.", "Attributes": [ { "FamilyName": "Identity and Access Management", - "FamilyDescription": "Controls that restrict who can change or query load-balancer resources.\n", - "Section": "CCC.LB.C05 Validate Session Affinity", + "FamilyDescription": "Controls that restrict who can change or query load-balancer resources. ", + "Section": "CCC.LB.CN05 Validate Session Affinity", "SubSection": "", - "SubSectionObjective": "Configure session persistence to minimise fixation and hijacking\nrisks.", + "SubSectionObjective": "Configure session persistence to minimise fixation and hijacking risks.", "Applicability": [ "tlp-green", "tlp-amber", @@ -2162,15 +1388,15 @@ ] }, { - "Id": "CCC.LB.C09.TR01", - "Description": "When an API call originates outside the approved CIDR\nset, the request MUST be denied.", + "Id": "CCC.LB.CN09.AR01", + "Description": "When an API call originates outside the approved CIDR set, the request MUST be denied.", "Attributes": [ { "FamilyName": "Identity and Access Management", - "FamilyDescription": "Controls that restrict who can change or query load-balancer resources.\n", - "Section": "CCC.LB.C09 Restrict Management API Access", + "FamilyDescription": "Controls that restrict who can change or query load-balancer resources. ", + "Section": "CCC.LB.CN09 Restrict Management API Access", "SubSection": "", - "SubSectionObjective": "Limit load-balancer API calls to authorised identities and\ntrusted networks.", + "SubSectionObjective": "Limit load-balancer API calls to authorised identities and trusted networks.", "Applicability": [ "tlp-green", "tlp-amber", @@ -2208,15 +1434,15 @@ ] }, { - "Id": "CCC.LB.C02.TR01", - "Description": "When concurrent connections reach 80 percent of capacity, the\nautoscaling group MUST add at least one instance within five\nminutes.", + "Id": "CCC.LB.CN02.AR01", + "Description": "When concurrent connections reach 80 percent of capacity, the autoscaling group MUST add at least one instance within five minutes.", "Attributes": [ { "FamilyName": "Data", - "FamilyDescription": "Controls that preserve availability and confidentiality of\ntraffic processed by the load balancer.\n", - "Section": "CCC.LB.C02 Auto-Scale Load Balancer Capacity", + "FamilyDescription": "Controls that preserve availability and confidentiality of traffic processed by the load balancer. ", + "Section": "CCC.LB.CN02 Auto-Scale Load Balancer Capacity", "SubSection": "", - "SubSectionObjective": "Expand load-balancer capacity to maintain availability during traffic\nspikes.", + "SubSectionObjective": "Expand load-balancer capacity to maintain availability during traffic spikes.", "Applicability": [ "tlp-green", "tlp-amber", @@ -2256,15 +1482,15 @@ ] }, { - "Id": "CCC.LB.C07.TR01", - "Description": "When responses pass through the load balancer, the\n\"Server\" header MUST be replaced with \"lb\".", + "Id": "CCC.LB.CN07.AR01", + "Description": "When responses pass through the load balancer, the \"Server\" header MUST be replaced with \"lb\".", "Attributes": [ { "FamilyName": "Data", - "FamilyDescription": "Controls that preserve availability and confidentiality of\ntraffic processed by the load balancer.\n", - "Section": "CCC.LB.C07 Scrub Sensitive Headers", + "FamilyDescription": "Controls that preserve availability and confidentiality of traffic processed by the load balancer. ", + "Section": "CCC.LB.CN07 Scrub Sensitive Headers", "SubSection": "", - "SubSectionObjective": "Remove headers that disclose internal details or software\nversions from HTTP responses.", + "SubSectionObjective": "Remove headers that disclose internal details or software versions from HTTP responses.", "Applicability": [ "tlp-green", "tlp-amber", @@ -2298,15 +1524,15 @@ "Checks": [] }, { - "Id": "CCC.LB.C08.TR01", - "Description": "When a certificate is within 30 days of expiry, automated renewal\nMUST complete and deploy a new certificate within 24 hours.", + "Id": "CCC.LB.CN08.AR01", + "Description": "When a certificate is within 30 days of expiry, automated renewal MUST complete and deploy a new certificate within 24 hours.", "Attributes": [ { "FamilyName": "Encryption", "FamilyDescription": "Controls that ensure trustworthy TLS certificates and ciphers.", - "Section": "CCC.LB.C08 Automate Certificate Renewal", + "Section": "CCC.LB.CN08 Automate Certificate Renewal", "SubSection": "", - "SubSectionObjective": "Maintain valid TLS certificates by automating renewal and\ndeployment before expiry.", + "SubSectionObjective": "Maintain valid TLS certificates by automating renewal and deployment before expiry.", "Applicability": [ "tlp-green", "tlp-amber", @@ -2344,15 +1570,15 @@ ] }, { - "Id": "CCC.Logging.C01.TR01", - "Description": "When a new cloud account is created, provider-level audit and network flow logging MUST be\nenabled by default and directed to the central sink.", + "Id": "CCC.Logging.CN01.AR01", + "Description": "When a new cloud account is created, provider-level audit and network flow logging MUST be enabled by default and directed to the central sink.", "Attributes": [ { "FamilyName": "Data", - "FamilyDescription": "Controls related to the confidentiality, integrity and availability of log data.\n", - "Section": "CCC.Logging.C01 Centralized and Comprehensive Log Aggregation", + "FamilyDescription": "Controls related to the confidentiality, integrity and availability of log data. ", + "Section": "CCC.Logging.CN01 Centralized and Comprehensive Log Aggregation", "SubSection": "", - "SubSectionObjective": "Ensure all operational and security logs from across the cloud environment, including\napplications, operating systems, network traffic, and cloud service activity, are captured\nautomatically and streamed to a central, secure log management service.", + "SubSectionObjective": "Ensure all operational and security logs from across the cloud environment, including applications, operating systems, network traffic, and cloud service activity, are captured automatically and streamed to a central, secure log management service.", "Applicability": [ "tlp-clear", "tlp-green", @@ -2402,15 +1628,15 @@ ] }, { - "Id": "CCC.Logging.C01.TR02", - "Description": "When a new cloud compute resource is deployed, it MUST be configured to forward all relevant\nlogs (e.g., OS, application, service logs) to the central log sink.", + "Id": "CCC.Logging.CN01.AR02", + "Description": "When a new cloud compute resource is deployed, it MUST be configured to forward all relevant logs (e.g., OS, application, service logs) to the central log sink.", "Attributes": [ { "FamilyName": "Data", - "FamilyDescription": "Controls related to the confidentiality, integrity and availability of log data.\n", - "Section": "CCC.Logging.C01 Centralized and Comprehensive Log Aggregation", + "FamilyDescription": "Controls related to the confidentiality, integrity and availability of log data. ", + "Section": "CCC.Logging.CN01 Centralized and Comprehensive Log Aggregation", "SubSection": "", - "SubSectionObjective": "Ensure all operational and security logs from across the cloud environment, including\napplications, operating systems, network traffic, and cloud service activity, are captured\nautomatically and streamed to a central, secure log management service.", + "SubSectionObjective": "Ensure all operational and security logs from across the cloud environment, including applications, operating systems, network traffic, and cloud service activity, are captured automatically and streamed to a central, secure log management service.", "Applicability": [ "tlp-clear", "tlp-green", @@ -2459,15 +1685,15 @@ ] }, { - "Id": "CCC.Logging.C02.TR01", - "Description": "When a new log bucket or stream is created, its retention policy MUST be configured\nin accordance with organisation's data retention policy.", + "Id": "CCC.Logging.CN02.AR01", + "Description": "When a new log bucket or stream is created, its retention policy MUST be configured in accordance with organisation's data retention policy.", "Attributes": [ { "FamilyName": "Data", - "FamilyDescription": "Controls related to the confidentiality, integrity and availability of log data.\n", - "Section": "CCC.Logging.C02 Enforce Data Retention Policy for Logs", + "FamilyDescription": "Controls related to the confidentiality, integrity and availability of log data. ", + "Section": "CCC.Logging.CN02 Enforce Data Retention Policy for Logs", "SubSection": "", - "SubSectionObjective": "Ensure that the retention period configured for logs aligns with the organization's\ndata retention policy.", + "SubSectionObjective": "Ensure that the retention period configured for logs aligns with the organization's data retention policy.", "Applicability": [ "tlp-clear", "tlp-green", @@ -2504,15 +1730,15 @@ ] }, { - "Id": "CCC.Logging.C02.TR02", - "Description": "When a query is performed to retrieve log events older than the number of days defined\nin the organisation's data retention policy, it MUST return an empty result.", + "Id": "CCC.Logging.CN02.AR02", + "Description": "When a query is performed to retrieve log events older than the number of days defined in the organisation's data retention policy, it MUST return an empty result.", "Attributes": [ { "FamilyName": "Data", - "FamilyDescription": "Controls related to the confidentiality, integrity and availability of log data.\n", - "Section": "CCC.Logging.C02 Enforce Data Retention Policy for Logs", + "FamilyDescription": "Controls related to the confidentiality, integrity and availability of log data. ", + "Section": "CCC.Logging.CN02 Enforce Data Retention Policy for Logs", "SubSection": "", - "SubSectionObjective": "Ensure that the retention period configured for logs aligns with the organization's\ndata retention policy.", + "SubSectionObjective": "Ensure that the retention period configured for logs aligns with the organization's data retention policy.", "Applicability": [ "tlp-clear", "tlp-green", @@ -2549,20 +1775,20 @@ ] }, { - "Id": "CCC.AuditLog.C08.TR01", - "Description": "When an attempt is made to modify or delete data before the object\nlock period expires, then the action MUST be denied.", + "Id": "CCC.AuditLog.CN08.AR01", + "Description": "When an attempt is made to modify or delete data before the object lock period expires, then the action MUST be denied.", "Attributes": [ { "FamilyName": "Data", - "FamilyDescription": "Controls related to the confidentiality, integrity and availability of log data.\n", - "Section": "CCC.Logging.C03 Enable Object Lock On Log Bucket", + "FamilyDescription": "Controls related to the confidentiality, integrity and availability of log data. ", + "Section": "CCC.Logging.CN03 Enable Object Lock On Log Bucket", "SubSection": "", - "SubSectionObjective": "Ensure log immutability by enabling Write Once, Read Many (WORM) protection\nusing object lock on log storage buckets. This prevents logs from being modified\nor deleted during the defined retention period, supporting compliance and forensic\nintegrity.", + "SubSectionObjective": "Ensure log immutability by enabling Write Once, Read Many (WORM) protection using object lock on log storage buckets. This prevents logs from being modified or deleted during the defined retention period, supporting compliance and forensic integrity.", "Applicability": [ "tlp-red", "tlp-amber" ], - "Recommendation": "Configure object lock policy.\n", + "Recommendation": "Configure object lock policy. ", "SectionThreatMappings": [ { "ReferenceId": "CCC", @@ -2593,20 +1819,20 @@ ] }, { - "Id": "CCC.AuditLog.C04.TR01", + "Id": "CCC.AuditLog.CN04.AR01", "Description": "When restricted fields are accessed by unauthorized users, then those fields MUST remain masked.", "Attributes": [ { "FamilyName": "Identity and Access Management", - "FamilyDescription": "Controls that restrict who can access and modify logs.\n", - "Section": "CCC.Logging.C04 Restrict Field And Log Type Access", + "FamilyDescription": "Controls that restrict who can access and modify logs. ", + "Section": "CCC.Logging.CN04 Restrict Field And Log Type Access", "SubSection": "", - "SubSectionObjective": "Configure access to logs to follow the principle of least privilege in particular where technically\npossible limit the log fields users have access to to prevent accidental exposure to sensitive\ninformation such as PII.", + "SubSectionObjective": "Configure access to logs to follow the principle of least privilege in particular where technically possible limit the log fields users have access to to prevent accidental exposure to sensitive information such as PII.", "Applicability": [ "tlp-red", "tlp-amber" ], - "Recommendation": "Review field level access controls on log data.\n", + "Recommendation": "Review field level access controls on log data. ", "SectionThreatMappings": [ { "ReferenceId": "CCC", @@ -2642,21 +1868,21 @@ ] }, { - "Id": "CCC.Logging.C05.TR01", - "Description": "When a log storage bucket is created, the bucket's access control settings MUST\nexplicitly deny public read and write access.", + "Id": "CCC.Logging.CN05.AR01", + "Description": "When a log storage bucket is created, the bucket's access control settings MUST explicitly deny public read and write access.", "Attributes": [ { "FamilyName": "Identity and Access Management", - "FamilyDescription": "Controls that restrict who can access and modify logs.\n", - "Section": "CCC.Logging.C05 Ensure Log Bucket is Not Publicly Accessible", + "FamilyDescription": "Controls that restrict who can access and modify logs. ", + "Section": "CCC.Logging.CN05 Ensure Log Bucket is Not Publicly Accessible", "SubSection": "", - "SubSectionObjective": "Ensure that log storage buckets are not publicly accessible to prevent unauthorized\naccess to sensitive log data. In addition, logs should be replicated to another cloud\nregion to enhance availability, durability, and support disaster recovery requirements.", + "SubSectionObjective": "Ensure that log storage buckets are not publicly accessible to prevent unauthorized access to sensitive log data. In addition, logs should be replicated to another cloud region to enhance availability, durability, and support disaster recovery requirements.", "Applicability": [ "tlp-red", "tlp-amber", "tlp-green" ], - "Recommendation": "Configure bucket policies and access control lists (ACLs) to restrict public access.\nRegularly review bucket permissions to ensure no public access has been inadvertently granted.\n", + "Recommendation": "Configure bucket policies and access control lists (ACLs) to restrict public access. Regularly review bucket permissions to ensure no public access has been inadvertently granted. ", "SectionThreatMappings": [ { "ReferenceId": "CCC", @@ -2695,21 +1921,21 @@ ] }, { - "Id": "CCC.Logging.C05.TR02", - "Description": "When the URL of a log storage bucket's object is accessed publicly, the action MUST be denied\nby bucket policy.", + "Id": "CCC.Logging.CN05.AR02", + "Description": "When the URL of a log storage bucket's object is accessed publicly, the action MUST be denied by bucket policy.", "Attributes": [ { "FamilyName": "Identity and Access Management", - "FamilyDescription": "Controls that restrict who can access and modify logs.\n", - "Section": "CCC.Logging.C05 Ensure Log Bucket is Not Publicly Accessible", + "FamilyDescription": "Controls that restrict who can access and modify logs. ", + "Section": "CCC.Logging.CN05 Ensure Log Bucket is Not Publicly Accessible", "SubSection": "", - "SubSectionObjective": "Ensure that log storage buckets are not publicly accessible to prevent unauthorized\naccess to sensitive log data. In addition, logs should be replicated to another cloud\nregion to enhance availability, durability, and support disaster recovery requirements.", + "SubSectionObjective": "Ensure that log storage buckets are not publicly accessible to prevent unauthorized access to sensitive log data. In addition, logs should be replicated to another cloud region to enhance availability, durability, and support disaster recovery requirements.", "Applicability": [ "tlp-red", "tlp-amber", "tlp-green" ], - "Recommendation": "Configure bucket policies and access control lists (ACLs) to restrict public access.\nRegularly review bucket permissions to ensure no public access has been inadvertently granted.\n", + "Recommendation": "Configure bucket policies and access control lists (ACLs) to restrict public access. Regularly review bucket permissions to ensure no public access has been inadvertently granted. ", "SectionThreatMappings": [ { "ReferenceId": "CCC", @@ -2745,15 +1971,15 @@ ] }, { - "Id": "CCC.Logging.C06.TR01", - "Description": "When a single principal executes an anomalously high number of log queries,\nan alert MUST be generated.", + "Id": "CCC.Logging.CN06.AR01", + "Description": "When a single principal executes an anomalously high number of log queries, an alert MUST be generated.", "Attributes": [ { "FamilyName": "Logging and Monitoring", - "FamilyDescription": "Controls that collect, alert, and retain logging-related events.\n", - "Section": "CCC.Logging.C06 Detect and Alert on Potential Log Exfiltration", + "FamilyDescription": "Controls that collect, alert, and retain logging-related events. ", + "Section": "CCC.Logging.CN06 Detect and Alert on Potential Log Exfiltration", "SubSection": "", - "SubSectionObjective": "Identify and alert on anomalous data access patterns that may indicate an attempt\nto exfiltrate log data.", + "SubSectionObjective": "Identify and alert on anomalous data access patterns that may indicate an attempt to exfiltrate log data.", "Applicability": [ "tlp-green", "tlp-amber", @@ -2793,15 +2019,15 @@ ] }, { - "Id": "CCC.Logging.C07.TR01", - "Description": "When an audit log event is recorded that corresponds to a modification of the logging service\nconfiguration such as disabling a log trail, deleting a log sink, or altering a log forwarding rule,\nan alert MUST be generated.", + "Id": "CCC.Logging.CN07.AR01", + "Description": "When an audit log event is recorded that corresponds to a modification of the logging service configuration such as disabling a log trail, deleting a log sink, or altering a log forwarding rule, an alert MUST be generated.", "Attributes": [ { "FamilyName": "Logging and Monitoring", - "FamilyDescription": "Controls that collect, alert, and retain logging-related events.\n", - "Section": "CCC.Logging.C07 Detect and Alert on Log Service Tampering", + "FamilyDescription": "Controls that collect, alert, and retain logging-related events. ", + "Section": "CCC.Logging.CN07 Detect and Alert on Log Service Tampering", "SubSection": "", - "SubSectionObjective": "Alert when any component of the critical logging infrastructure is disabled, modified,\nor deleted, indicating a defense evasion attempt.", + "SubSectionObjective": "Alert when any component of the critical logging infrastructure is disabled, modified, or deleted, indicating a defense evasion attempt.", "Applicability": [ "tlp-clear", "tlp-green", @@ -2850,13 +2076,13 @@ ] }, { - "Id": "CCC.ObjStor.C01.TR01", + "Id": "CCC.ObjStor.CN01.AR01", "Description": "When a request is made to read a protected bucket, the service MUST prevent any request using KMS keys not listed as trusted by the organization.", "Attributes": [ { "FamilyName": "Data", "FamilyDescription": "TODO: Describe this control family", - "Section": "CCC.C01 Prevent Unencrypted Requests", + "Section": "CCC.CN01 Prevent Unencrypted Requests", "SubSection": "CCC.ObjStor.C01 Prevent Requests to Buckets or Objects with Untrusted KMS Keys", "SubSectionObjective": "Prevent any requests to object storage buckets or objects using untrusted KMS keys to protect against unauthorized data encryption that can impact data availability and integrity.", "Applicability": [ @@ -2910,13 +2136,13 @@ ] }, { - "Id": "CCC.ObjStor.C01.TR02", + "Id": "CCC.ObjStor.CN01.AR02", "Description": "When a request is made to read a protected object, the service MUST prevent any request using KMS keys not listed as trusted by the organization.", "Attributes": [ { "FamilyName": "Data", "FamilyDescription": "TODO: Describe this control family", - "Section": "CCC.C01 Prevent Unencrypted Requests", + "Section": "CCC.CN01 Prevent Unencrypted Requests", "SubSection": "CCC.ObjStor.C01 Prevent Requests to Buckets or Objects with Untrusted KMS Keys", "SubSectionObjective": "Prevent any requests to object storage buckets or objects using untrusted KMS keys to protect against unauthorized data encryption that can impact data availability and integrity.", "Applicability": [ @@ -2970,13 +2196,13 @@ ] }, { - "Id": "CCC.ObjStor.C01.TR03", + "Id": "CCC.ObjStor.CN01.AR03", "Description": "When a request is made to write to a bucket, the service MUST prevent any request using KMS keys not listed as trusted by the organization.", "Attributes": [ { "FamilyName": "Data", "FamilyDescription": "TODO: Describe this control family", - "Section": "CCC.C01 Prevent Unencrypted Requests", + "Section": "CCC.CN01 Prevent Unencrypted Requests", "SubSection": "CCC.ObjStor.C01 Prevent Requests to Buckets or Objects with Untrusted KMS Keys", "SubSectionObjective": "Prevent any requests to object storage buckets or objects using untrusted KMS keys to protect against unauthorized data encryption that can impact data availability and integrity.", "Applicability": [ @@ -3033,13 +2259,13 @@ ] }, { - "Id": "CCC.ObjStor.C01.TR04", + "Id": "CCC.ObjStor.CN01.AR04", "Description": "When a request is made to write to an object, the service MUST prevent any request using KMS keys not listed as trusted by the organization.", "Attributes": [ { "FamilyName": "Data", "FamilyDescription": "TODO: Describe this control family", - "Section": "CCC.C01 Prevent Unencrypted Requests", + "Section": "CCC.CN01 Prevent Unencrypted Requests", "SubSection": "CCC.ObjStor.C01 Prevent Requests to Buckets or Objects with Untrusted KMS Keys", "SubSectionObjective": "Prevent any requests to object storage buckets or objects using untrusted KMS keys to protect against unauthorized data encryption that can impact data availability and integrity.", "Applicability": [ @@ -3096,13 +2322,13 @@ ] }, { - "Id": "CCC.ObjStor.C03.TR01", + "Id": "CCC.ObjStor.CN03.AR01", "Description": "When an object storage bucket deletion is attempted, the bucket MUST be fully recoverable for a set time-frame after deletion is requested.", "Attributes": [ { "FamilyName": "Data", "FamilyDescription": "TODO: Describe this control family", - "Section": "CCC.C03 Implement Multi-factor Authentication (MFA) for Access", + "Section": "CCC.CN03 Implement Multi-factor Authentication (MFA) for Access", "SubSection": "CCC.ObjStor.C03 Prevent Bucket Deletion Through Irrevocable Bucket Retention Policy", "SubSectionObjective": "Ensure that object storage bucket is not deleted after creation, and that the preventative measure cannot be unset.", "Applicability": [ @@ -3156,13 +2382,13 @@ ] }, { - "Id": "CCC.ObjStor.C03.TR02", + "Id": "CCC.ObjStor.CN03.AR02", "Description": "When an attempt is made to modify the retention policy for an object storage bucket, the service MUST prevent the policy from being modified.", "Attributes": [ { "FamilyName": "Data", "FamilyDescription": "TODO: Describe this control family", - "Section": "CCC.C03 Implement Multi-factor Authentication (MFA) for Access", + "Section": "CCC.CN03 Implement Multi-factor Authentication (MFA) for Access", "SubSection": "CCC.ObjStor.C03 Prevent Bucket Deletion Through Irrevocable Bucket Retention Policy", "SubSectionObjective": "Ensure that object storage bucket is not deleted after creation, and that the preventative measure cannot be unset.", "Applicability": [ @@ -3215,13 +2441,13 @@ ] }, { - "Id": "CCC.ObjStor.C04.TR01", + "Id": "CCC.ObjStor.CN04.AR01", "Description": "When an object is uploaded to the object storage system, the object MUST automatically receive a default retention policy that prevents premature deletion or modification.", "Attributes": [ { "FamilyName": "Data", "FamilyDescription": "TODO: Describe this control family", - "Section": "CCC.C04 Log All Access and Changes", + "Section": "CCC.CN04 Log All Access and Changes", "SubSection": "CCC.ObjStor.C04 Objects have an Effective Retention Policy by Default", "SubSectionObjective": "Ensure that all objects stored in the object storage system have a retention policy applied by default, preventing premature deletion or modification of objects and ensuring compliance with data retention regulations.", "Applicability": [ @@ -3275,13 +2501,13 @@ ] }, { - "Id": "CCC.ObjStor.C04.TR02", + "Id": "CCC.ObjStor.CN04.AR02", "Description": "When an attempt is made to delete or modify an object that is subject to an active retention policy, the service MUST prevent the action from being completed.", "Attributes": [ { "FamilyName": "Data", "FamilyDescription": "TODO: Describe this control family", - "Section": "CCC.C04 Log All Access and Changes", + "Section": "CCC.CN04 Log All Access and Changes", "SubSection": "CCC.ObjStor.C04 Objects have an Effective Retention Policy by Default", "SubSectionObjective": "Ensure that all objects stored in the object storage system have a retention policy applied by default, preventing premature deletion or modification of objects and ensuring compliance with data retention regulations.", "Applicability": [ @@ -3334,13 +2560,13 @@ ] }, { - "Id": "CCC.ObjStor.C05.TR01", + "Id": "CCC.ObjStor.CN05.AR01", "Description": "When an object is uploaded to the object storage bucket, the object MUST be stored with a unique identifier.", "Attributes": [ { "FamilyName": "Data", "FamilyDescription": "TODO: Describe this control family", - "Section": "CCC.C05 Prevent Access from Untrusted Entities", + "Section": "CCC.CN05 Prevent Access from Untrusted Entities", "SubSection": "CCC.ObjStor.C05 Versioning is Enabled for All Objects in the Bucket", "SubSectionObjective": "Ensure that versioning is enabled for all objects stored in the object storage bucket to enable recovery of previous versions of objects in case of loss or corruption.", "Applicability": [ @@ -3393,13 +2619,13 @@ ] }, { - "Id": "CCC.ObjStor.C05.TR02", + "Id": "CCC.ObjStor.CN05.AR02", "Description": "When an object is modified, the service MUST assign a new unique identifier to the modified object to differentiate it from the previous version.", "Attributes": [ { "FamilyName": "Data", "FamilyDescription": "TODO: Describe this control family", - "Section": "CCC.C05 Prevent Access from Untrusted Entities", + "Section": "CCC.CN05 Prevent Access from Untrusted Entities", "SubSection": "CCC.ObjStor.C05 Versioning is Enabled for All Objects in the Bucket", "SubSectionObjective": "Ensure that versioning is enabled for all objects stored in the object storage bucket to enable recovery of previous versions of objects in case of loss or corruption.", "Applicability": [ @@ -3454,13 +2680,13 @@ ] }, { - "Id": "CCC.ObjStor.C05.TR03", + "Id": "CCC.ObjStor.CN05.AR03", "Description": "When an object is modified, the service MUST allow for recovery of previous versions of the object.", "Attributes": [ { "FamilyName": "Data", "FamilyDescription": "TODO: Describe this control family", - "Section": "CCC.C05 Prevent Access from Untrusted Entities", + "Section": "CCC.CN05 Prevent Access from Untrusted Entities", "SubSection": "CCC.ObjStor.C05 Versioning is Enabled for All Objects in the Bucket", "SubSectionObjective": "Ensure that versioning is enabled for all objects stored in the object storage bucket to enable recovery of previous versions of objects in case of loss or corruption.", "Applicability": [ @@ -3514,13 +2740,13 @@ ] }, { - "Id": "CCC.ObjStor.C05.TR04", + "Id": "CCC.ObjStor.CN05.AR04", "Description": "When an object is deleted, the service MUST retain other versions of the object to allow for recovery of previous versions.", "Attributes": [ { "FamilyName": "Data", "FamilyDescription": "TODO: Describe this control family", - "Section": "CCC.C05 Prevent Access from Untrusted Entities", + "Section": "CCC.CN05 Prevent Access from Untrusted Entities", "SubSection": "CCC.ObjStor.C05 Versioning is Enabled for All Objects in the Bucket", "SubSectionObjective": "Ensure that versioning is enabled for all objects stored in the object storage bucket to enable recovery of previous versions of objects in case of loss or corruption.", "Applicability": [ @@ -3574,13 +2800,13 @@ ] }, { - "Id": "CCC.ObjStor.C06.TR01", + "Id": "CCC.ObjStor.CN06.AR01", "Description": "When an object storage bucket is accessed, the service MUST store access logs in a separate data store.", "Attributes": [ { "FamilyName": "Data", "FamilyDescription": "TODO: Describe this control family", - "Section": "CCC.C06 Prevent Deployment in Restricted Regions", + "Section": "CCC.CN06 Prevent Deployment in Restricted Regions", "SubSection": "CCC.ObjStor.C06 Access Logs are Stored in a Separate Data Store", "SubSectionObjective": "Ensure that access logs for object storage buckets are stored in a separate data store to protect against unauthorized access, tampering, or deletion of logs (Logbuckets are exempt from this requirement, but must be tlp-red).", "Applicability": [ @@ -3634,13 +2860,13 @@ ] }, { - "Id": "CCC.ObjStor.C02.TR01", + "Id": "CCC.ObjStor.CN02.AR01", "Description": "When a permission set is allowed for an object in a bucket, the service MUST allow the same permission set to access all objects in the same bucket.", "Attributes": [ { "FamilyName": "Identity and Access Management", "FamilyDescription": "TODO: Describe this control family", - "Section": "CCC.C02 Ensure Data Encryption at Rest for All Stored Data", + "Section": "CCC.CN02 Ensure Data Encryption at Rest for All Stored Data", "SubSection": "CCC.ObjStor.C02 Enforce Uniform Bucket-level Access to Prevent Inconsistent Permissions", "SubSectionObjective": "Ensure that uniform bucket-level access is enforced across all object storage buckets. This prevents the use of ad-hoc or inconsistent object-level permissions, ensuring centralized, consistent, and secure access management in accordance with the principle of least privilege.", "Applicability": [ @@ -3692,13 +2918,13 @@ ] }, { - "Id": "CCC.ObjStor.C02.TR02", + "Id": "CCC.ObjStor.CN02.AR02", "Description": "When a permission set is denied for an object in a bucket, the service MUST deny the same permission set to access all objects in the same bucket.", "Attributes": [ { "FamilyName": "Identity and Access Management", "FamilyDescription": "TODO: Describe this control family", - "Section": "CCC.C02 Ensure Data Encryption at Rest for All Stored Data", + "Section": "CCC.CN02 Ensure Data Encryption at Rest for All Stored Data", "SubSection": "CCC.ObjStor.C02 Enforce Uniform Bucket-level Access to Prevent Inconsistent Permissions", "SubSectionObjective": "Ensure that uniform bucket-level access is enforced across all object storage buckets. This prevents the use of ad-hoc or inconsistent object-level permissions, ensuring centralized, consistent, and secure access management in accordance with the principle of least privilege.", "Applicability": [ @@ -3751,972 +2977,9 @@ "s3_bucket_public_access" ] }, - { - "Id": "CCC.MLDE.CN01.AR01", - "Description": "Verify that only authorized users can access MLDE resources,\nand that access modes are properly defined and enforced.", - "Attributes": [ - { - "FamilyName": "Identity and Access Management", - "FamilyDescription": "TODO: Describe this control family", - "Section": "CCC.MLDE.CN01 Define Access Mode for ML Development Environments", - "SubSection": "", - "SubSectionObjective": "Ensure that access to Machine Learning Development Environment (MLDE)\nresources is strictly defined and controlled.\nOnly authorized users with appropriate permissions can access these environments,\nmitigating the risk of unauthorized access, data leakage, or service disruption.", - "Applicability": [ - "tlp-red", - "tlp-amber", - "tlp-green", - "tlp-clear" - ], - "Recommendation": "", - "SectionThreatMappings": [ - { - "ReferenceId": "CCC", - "Identifiers": [ - "CCC.MLDE.TH01", - "CCC.TH01" - ] - } - ], - "SectionGuidelineMappings": [ - { - "ReferenceId": "NIST-CSF", - "Identifiers": [ - "PR.AC-3" - ] - }, - { - "ReferenceId": "ISO_27001", - "Identifiers": [ - "2013 A.9.1.1", - "2013 A.9.2.1" - ] - }, - { - "ReferenceId": "NIST_800_53", - "Identifiers": [ - "AC-2", - "AC-3" - ] - }, - { - "ReferenceId": "CCM", - "Identifiers": [ - "IAM-01", - "IAM-02" - ] - } - ] - } - ], - "Checks": [ - "accessanalyzer_enabled", - "accessanalyzer_enabled_without_findings", - "iam_root_mfa_enabled", - "iam_root_credentials_management_enabled", - "iam_avoid_root_usage", - "iam_user_mfa_enabled_console_access", - "awslambda_function_not_publicly_accessible", - "awslambda_function_url_public", - "iam_group_administrator_access_policy", - "iam_user_administrator_access_policy", - "iam_policy_attached_only_to_group_or_roles", - "iam_inline_policy_no_full_access_to_cloudtrail", - "iam_inline_policy_no_full_access_to_kms", - "iam_policy_allows_privilege_escalation", - "s3_bucket_public_access", - "s3_bucket_public_list_acl", - "s3_bucket_public_write_acl", - "s3_account_level_public_access_blocks", - "s3_bucket_cross_account_access" - ] - }, - { - "Id": "CCC.MLDE.CN03.AR01", - "Description": "Verify that root access is disabled on MLDE instances containing sensitive data.", - "Attributes": [ - { - "FamilyName": "Identity and Access Management", - "FamilyDescription": "TODO: Describe this control family", - "Section": "CCC.MLDE.CN03 Disable Root Access on MLDE Instances", - "SubSection": "", - "SubSectionObjective": "Prevent users from obtaining root access on MLDE instances to reduce the\nrisk of unauthorized system modifications and potential security breaches.", - "Applicability": [ - "tlp-red" - ], - "Recommendation": "", - "SectionThreatMappings": [ - { - "ReferenceId": "CCC", - "Identifiers": [ - "CCC.MLDE.TH01" - ] - } - ], - "SectionGuidelineMappings": [ - { - "ReferenceId": "NIST-CSF", - "Identifiers": [ - "PR.AC-4" - ] - }, - { - "ReferenceId": "NIST_800_53", - "Identifiers": [ - "AC-6" - ] - }, - { - "ReferenceId": "CCM", - "Identifiers": [ - "IAM-08", - "IAM-12" - ] - }, - { - "ReferenceId": "ISO_27001", - "Identifiers": [ - "2013 A.9.2.3" - ] - } - ] - } - ], - "Checks": [] - }, - { - "Id": "CCC.MLDE.CN03.AR02", - "Description": "For MLDE instances without sensitive data, ensure that root access is only\nenabled when necessary and properly authorized.", - "Attributes": [ - { - "FamilyName": "Identity and Access Management", - "FamilyDescription": "TODO: Describe this control family", - "Section": "CCC.MLDE.CN03 Disable Root Access on MLDE Instances", - "SubSection": "", - "SubSectionObjective": "Prevent users from obtaining root access on MLDE instances to reduce the\nrisk of unauthorized system modifications and potential security breaches.", - "Applicability": [ - "tlp-red", - "tlp-amber", - "tlp-green", - "tlp-clear" - ], - "Recommendation": "", - "SectionThreatMappings": [ - { - "ReferenceId": "CCC", - "Identifiers": [ - "CCC.MLDE.TH01" - ] - } - ], - "SectionGuidelineMappings": [ - { - "ReferenceId": "NIST-CSF", - "Identifiers": [ - "PR.AC-4" - ] - }, - { - "ReferenceId": "NIST_800_53", - "Identifiers": [ - "AC-6" - ] - }, - { - "ReferenceId": "CCM", - "Identifiers": [ - "IAM-08", - "IAM-12" - ] - }, - { - "ReferenceId": "ISO_27001", - "Identifiers": [ - "2013 A.9.2.3" - ] - } - ] - } - ], - "Checks": [ - "ec2_instance_port_ssh_exposed_to_internet", - "ec2_instance_managed_by_ssm", - "ec2_instance_imdsv2_enabled", - "ec2_launch_template_imdsv2_required", - "ec2_instance_account_imdsv2_enabled", - "ec2_instance_public_ip" - ] - }, - { - "Id": "CCC.MLDE.CN04.AR01", - "Description": "Verify that terminal access is disabled on MLDE instances containing sensitive data.", - "Attributes": [ - { - "FamilyName": "Identity and Access Management", - "FamilyDescription": "TODO: Describe this control family", - "Section": "CCC.MLDE.CN04 Disable Terminal Access on MLDE Instances", - "SubSection": "", - "SubSectionObjective": "Prevent users from accessing the terminal on MLDE instances to limit the risk of\nunauthorized commands and potential system compromise.", - "Applicability": [ - "tlp-red" - ], - "Recommendation": "", - "SectionThreatMappings": [ - { - "ReferenceId": "CCC", - "Identifiers": [ - "CCC.MLDE.TH01" - ] - } - ], - "SectionGuidelineMappings": [ - { - "ReferenceId": "NIST-CSF", - "Identifiers": [ - "PR.AC-4" - ] - }, - { - "ReferenceId": "NIST_800_53", - "Identifiers": [ - "AC-6" - ] - }, - { - "ReferenceId": "CCM", - "Identifiers": [ - "IAM-08" - ] - }, - { - "ReferenceId": "ISO_27001", - "Identifiers": [ - "2013 A.9.2.3" - ] - } - ] - } - ], - "Checks": [ - "ec2_instance_port_ssh_exposed_to_internet", - "ec2_securitygroup_allow_ingress_from_internet_to_all_ports", - "ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22", - "ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389", - "ec2_instance_public_ip", - "ec2_instance_internet_facing_with_instance_profile" - ] - }, - { - "Id": "CCC.MLDE.CN04.AR02", - "Description": "For MLDE instances without sensitive data, ensure that terminal access is only\nenabled when necessary and properly authorized.", - "Attributes": [ - { - "FamilyName": "Identity and Access Management", - "FamilyDescription": "TODO: Describe this control family", - "Section": "CCC.MLDE.CN04 Disable Terminal Access on MLDE Instances", - "SubSection": "", - "SubSectionObjective": "Prevent users from accessing the terminal on MLDE instances to limit the risk of\nunauthorized commands and potential system compromise.", - "Applicability": [ - "tlp-red", - "tlp-amber", - "tlp-green", - "tlp-clear" - ], - "Recommendation": "", - "SectionThreatMappings": [ - { - "ReferenceId": "CCC", - "Identifiers": [ - "CCC.MLDE.TH01" - ] - } - ], - "SectionGuidelineMappings": [ - { - "ReferenceId": "NIST-CSF", - "Identifiers": [ - "PR.AC-4" - ] - }, - { - "ReferenceId": "NIST_800_53", - "Identifiers": [ - "AC-6" - ] - }, - { - "ReferenceId": "CCM", - "Identifiers": [ - "IAM-08" - ] - }, - { - "ReferenceId": "ISO_27001", - "Identifiers": [ - "2013 A.9.2.3" - ] - } - ] - } - ], - "Checks": [ - "ec2_instance_port_ssh_exposed_to_internet", - "ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22", - "ec2_securitygroup_allow_ingress_from_internet_to_all_ports", - "ec2_networkacl_allow_ingress_tcp_port_22", - "ec2_instance_public_ip", - "ec2_launch_template_no_public_ip", - "autoscaling_group_launch_configuration_no_public_ip" - ] - }, - { - "Id": "CCC.MLDE.CN02.AR01", - "Description": "Confirm that file download functionality is disabled on MLDE instances containing sensitive data.", - "Attributes": [ - { - "FamilyName": "Data Protection", - "FamilyDescription": "TODO: Describe this control family", - "Section": "CCC.MLDE.CN02 Disable File Downloads on MLDE Instances", - "SubSection": "", - "SubSectionObjective": "Prevent unauthorized file downloads from MLDE instances to protect sensitive data from being exfiltrated.", - "Applicability": [ - "tlp-red" - ], - "Recommendation": "", - "SectionThreatMappings": [ - { - "ReferenceId": "CCC", - "Identifiers": [ - "CCC.MLDE.TH02", - "CCC.TH02" - ] - } - ], - "SectionGuidelineMappings": [ - { - "ReferenceId": "NIST-CSF", - "Identifiers": [ - "PR.DS-5" - ] - }, - { - "ReferenceId": "CCM", - "Identifiers": [ - "DSI-05", - "DSI-07" - ] - }, - { - "ReferenceId": "ISO_27001", - "Identifiers": [ - "2013 A.13.2.1" - ] - }, - { - "ReferenceId": "NIST_800_53", - "Identifiers": [ - "SC-7", - "SC-8" - ] - } - ] - } - ], - "Checks": [] - }, - { - "Id": "CCC.MLDE.CN02.AR02", - "Description": "For MLDE instances without sensitive data, ensure that file downloads are monitored and logged.", - "Attributes": [ - { - "FamilyName": "Data Protection", - "FamilyDescription": "TODO: Describe this control family", - "Section": "", - "SubSection": "CCC.MLDE.CN02 Disable File Downloads on MLDE Instances", - "SubSectionObjective": "Prevent unauthorized file downloads from MLDE instances to protect sensitive data from being exfiltrated.", - "Applicability": [ - "tlp-red", - "tlp-amber", - "tlp-green", - "tlp-clear" - ], - "Recommendation": "", - "SectionThreatMappings": [ - { - "ReferenceId": "CCC", - "Identifiers": [ - "CCC.MLDE.TH02", - "CCC.TH02" - ] - } - ], - "SectionGuidelineMappings": [ - { - "ReferenceId": "NIST-CSF", - "Identifiers": [ - "PR.DS-5" - ] - }, - { - "ReferenceId": "CCM", - "Identifiers": [ - "DSI-05", - "DSI-07" - ] - }, - { - "ReferenceId": "ISO_27001", - "Identifiers": [ - "2013 A.13.2.1" - ] - }, - { - "ReferenceId": "NIST_800_53", - "Identifiers": [ - "SC-7", - "SC-8" - ] - } - ] - } - ], - "Checks": [ - "cloudtrail_s3_dataevents_read_enabled", - "cloudtrail_s3_dataevents_write_enabled", - "cloudtrail_kms_encryption_enabled", - "cloudtrail_cloudwatch_logging_enabled", - "cloudtrail_logs_s3_bucket_is_not_publicly_accessible" - ] - }, - { - "Id": "CCC.MLDE.CN05.AR01", - "Description": "Verify that only approved VM and container images can be selected when creating MLDE instances.", - "Attributes": [ - { - "FamilyName": "Configuration Management", - "FamilyDescription": "TODO: Describe this control family", - "Section": "", - "SubSection": "CCC.MLDE.CN05 Restrict Environment Options on MLDE Instances", - "SubSectionObjective": "Limit the virtual machine and container image options available when creating\nnew MLDE instances to approved and secure configurations.", - "Applicability": [ - "tlp-red", - "tlp-amber" - ], - "Recommendation": "", - "SectionThreatMappings": [ - { - "ReferenceId": "CCC", - "Identifiers": [ - "CCC.MLDE.TH04" - ] - } - ], - "SectionGuidelineMappings": [ - { - "ReferenceId": "NIST-CSF", - "Identifiers": [ - "PR.IP-1" - ] - }, - { - "ReferenceId": "CCM", - "Identifiers": [ - "TVM-02" - ] - }, - { - "ReferenceId": "ISO_27001", - "Identifiers": [ - "2013 A.12.5.1" - ] - }, - { - "ReferenceId": "NIST_800_53", - "Identifiers": [ - "CM-2" - ] - } - ] - } - ], - "Checks": [ - "bedrock_guardrail_prompt_attack_filter_enabled", - "bedrock_guardrail_sensitive_information_filter_enabled", - "bedrock_model_invocation_logging_enabled", - "bedrock_model_invocation_logs_encryption_enabled", - "bedrock_agent_guardrail_enabled" - ] - }, - { - "Id": "CCC.MLDE.CN05.AR02", - "Description": "Attempt to create an MLDE instance with an unapproved image and confirm that it is denied.", - "Attributes": [ - { - "FamilyName": "Configuration Management", - "FamilyDescription": "TODO: Describe this control family", - "Section": "", - "SubSection": "CCC.MLDE.CN05 Restrict Environment Options on MLDE Instances", - "SubSectionObjective": "Limit the virtual machine and container image options available when creating\nnew MLDE instances to approved and secure configurations.", - "Applicability": [ - "tlp-red" - ], - "Recommendation": "", - "SectionThreatMappings": [ - { - "ReferenceId": "CCC", - "Identifiers": [ - "CCC.MLDE.TH04" - ] - } - ], - "SectionGuidelineMappings": [ - { - "ReferenceId": "NIST-CSF", - "Identifiers": [ - "PR.IP-1" - ] - }, - { - "ReferenceId": "CCM", - "Identifiers": [ - "TVM-02" - ] - }, - { - "ReferenceId": "ISO_27001", - "Identifiers": [ - "2013 A.12.5.1" - ] - }, - { - "ReferenceId": "NIST_800_53", - "Identifiers": [ - "CM-2" - ] - } - ] - } - ], - "Checks": [] - }, - { - "Id": "CCC.MLDE.CN06.AR01", - "Description": "Verify that automatic scheduled upgrades are enabled on user-managed\nMLDE instances containing sensitive data.", - "Attributes": [ - { - "FamilyName": "Vulnerability Management", - "FamilyDescription": "TODO: Describe this control family", - "Section": "", - "SubSection": "CCC.MLDE.CN06 Require Automatic Scheduled Upgrades on User-Managed MLDE Instances", - "SubSectionObjective": "Ensure that MLDE instances are kept up-to-date with the\nlatest security patches by enforcing automatic scheduled upgrades.", - "Applicability": [ - "tlp-red" - ], - "Recommendation": "", - "SectionThreatMappings": [ - { - "ReferenceId": "CCC", - "Identifiers": [ - "CCC.MLDE.TH04", - "CCC.TH06" - ] - } - ], - "SectionGuidelineMappings": [ - { - "ReferenceId": "NIST-CSF", - "Identifiers": [ - "PR.IP-12" - ] - }, - { - "ReferenceId": "CCM", - "Identifiers": [ - "TVM-01", - "TVM-02" - ] - }, - { - "ReferenceId": "ISO_27001", - "Identifiers": [ - "2013 A.12.6.1" - ] - }, - { - "ReferenceId": "NIST_800_53", - "Identifiers": [ - "SI-2" - ] - } - ] - } - ], - "Checks": [ - "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", - "redshift_cluster_automatic_upgrades", - "rds_cluster_minor_version_upgrade_enabled", - "rds_instance_minor_version_upgrade_enabled" - ] - }, - { - "Id": "CCC.MLDE.CN06.AR02", - "Description": "Ensure that the upgrade schedule is appropriately configured and\ndoes not interfere with critical operations.", - "Attributes": [ - { - "FamilyName": "Vulnerability Management", - "FamilyDescription": "TODO: Describe this control family", - "Section": "", - "SubSection": "CCC.MLDE.CN06 Require Automatic Scheduled Upgrades on User-Managed MLDE Instances", - "SubSectionObjective": "Ensure that MLDE instances are kept up-to-date with the\nlatest security patches by enforcing automatic scheduled upgrades.", - "Applicability": [ - "tlp-red", - "tlp-amber", - "tlp-green", - "tlp-clear" - ], - "Recommendation": "", - "SectionThreatMappings": [ - { - "ReferenceId": "CCC", - "Identifiers": [ - "CCC.MLDE.TH04", - "CCC.TH06" - ] - } - ], - "SectionGuidelineMappings": [ - { - "ReferenceId": "NIST-CSF", - "Identifiers": [ - "PR.IP-12" - ] - }, - { - "ReferenceId": "CCM", - "Identifiers": [ - "TVM-01", - "TVM-02" - ] - }, - { - "ReferenceId": "ISO_27001", - "Identifiers": [ - "2013 A.12.6.1" - ] - }, - { - "ReferenceId": "NIST_800_53", - "Identifiers": [ - "SI-2" - ] - } - ] - } - ], - "Checks": [] - }, - { - "Id": "CCC.MLDE.CN07.AR01", - "Description": "Verify that MLDE instances containing sensitive data cannot be accessed via public IP addresses.", - "Attributes": [ - { - "FamilyName": "Network Security", - "FamilyDescription": "TODO: Describe this control family", - "Section": "", - "SubSection": "CCC.MLDE.CN07 Restrict Public IP Access on MLDE Instances", - "SubSectionObjective": "Prevent public IP access to MLDE instances to reduce exposure to the internet and enhance security.", - "Applicability": [ - "tlp-red" - ], - "Recommendation": "", - "SectionThreatMappings": [ - { - "ReferenceId": "CCC", - "Identifiers": [ - "CCC.MLDE.TH02", - "CCC.VPC.TH02" - ] - } - ], - "SectionGuidelineMappings": [ - { - "ReferenceId": "NIST-CSF", - "Identifiers": [ - "PR.AC-3" - ] - }, - { - "ReferenceId": "CCM", - "Identifiers": [ - "SEF-05" - ] - }, - { - "ReferenceId": "ISO_27001", - "Identifiers": [ - "2013 A.13.1.1" - ] - }, - { - "ReferenceId": "NIST_800_53", - "Identifiers": [ - "SC-7" - ] - } - ] - } - ], - "Checks": [ - "ec2_instance_public_ip", - "ec2_securitygroup_allow_ingress_from_internet_to_all_ports" - ] - }, - { - "Id": "CCC.MLDE.CN07.AR02", - "Description": "For MLDE instances without sensitive data requiring public access,\nensure that appropriate security controls are in place and access is approved.", - "Attributes": [ - { - "FamilyName": "Network Security", - "FamilyDescription": "TODO: Describe this control family", - "Section": "CCC.MLDE.CN07 Restrict Public IP Access on MLDE Instances", - "SubSection": "", - "SubSectionObjective": "Prevent public IP access to MLDE instances to reduce exposure to the internet and enhance security.", - "Applicability": [ - "tlp-red", - "tlp-amber", - "tlp-green", - "tlp-clear" - ], - "Recommendation": "", - "SectionThreatMappings": [ - { - "ReferenceId": "CCC", - "Identifiers": [ - "CCC.MLDE.TH02", - "CCC.VPC.TH02" - ] - } - ], - "SectionGuidelineMappings": [ - { - "ReferenceId": "NIST-CSF", - "Identifiers": [ - "PR.AC-3" - ] - }, - { - "ReferenceId": "CCM", - "Identifiers": [ - "SEF-05" - ] - }, - { - "ReferenceId": "ISO_27001", - "Identifiers": [ - "2013 A.13.1.1" - ] - }, - { - "ReferenceId": "NIST_800_53", - "Identifiers": [ - "SC-7" - ] - } - ] - } - ], - "Checks": [ - "ec2_instance_public_ip", - "ec2_instance_internet_facing_with_instance_profile", - "ec2_securitygroup_allow_ingress_from_internet_to_all_ports", - "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_tcp_port_postgres_5432", - "ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_mysql_3306", - "ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_oracle_1521_2483", - "ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_ftp_20_21", - "ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_memcached_11211", - "ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_redis_6379", - "ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_elasticsearch_kibana_9200_9300_5601", - "ec2_networkacl_allow_ingress_tcp_port_22", - "ec2_networkacl_allow_ingress_tcp_port_3389", - "ec2_networkacl_allow_ingress_any_port" - ] - }, - { - "Id": "CCC.MLDE.CN08.AR01", - "Description": "Verify that MLDE instances containing sensitive data can only be deployed in\napproved virtual networks with appropriate security controls.", - "Attributes": [ - { - "FamilyName": "Network Security", - "FamilyDescription": "TODO: Describe this control family", - "Section": "CCC.MLDE.CN08 Restrict Virtual Networks for MLDE Instances", - "SubSection": "", - "SubSectionObjective": "Limit the virtual networks that can be used when creating new MLDE instances to\nensure they are deployed within approved and secure network environments.", - "Applicability": [ - "tlp-red" - ], - "Recommendation": "", - "SectionThreatMappings": [ - { - "ReferenceId": "CCC", - "Identifiers": [ - "CCC.MLDE.TH01", - "CCC.TH01" - ] - } - ], - "SectionGuidelineMappings": [ - { - "ReferenceId": "NIST-CSF", - "Identifiers": [ - "PR.AC-4" - ] - }, - { - "ReferenceId": "CCM", - "Identifiers": [ - "IAM-12" - ] - }, - { - "ReferenceId": "ISO_27001", - "Identifiers": [ - "2013 A.9.1.2" - ] - }, - { - "ReferenceId": "NIST_800_53", - "Identifiers": [ - "AC-6" - ] - } - ] - } - ], - "Checks": [ - "vpc_subnet_no_public_ip_by_default", - "vpc_subnet_different_az", - "vpc_flow_logs_enabled", - "vpc_endpoint_connections_trust_boundaries", - "vpc_peering_routing_tables_with_least_privilege" - ] - }, - { - "Id": "CCC.MLDE.CN08.AR02", - "Description": "Ensure that MLDE instances without sensitive data are deployed in\nnetworks that meet organizational security standards.", - "Attributes": [ - { - "FamilyName": "Network Security", - "FamilyDescription": "TODO: Describe this control family", - "Section": "CCC.MLDE.CN08 Restrict Virtual Networks for MLDE Instances", - "SubSection": "", - "SubSectionObjective": "Limit the virtual networks that can be used when creating new MLDE instances to\nensure they are deployed within approved and secure network environments.", - "Applicability": [ - "tlp-red", - "tlp-amber", - "tlp-green", - "tlp-clear" - ], - "Recommendation": "", - "SectionThreatMappings": [ - { - "ReferenceId": "CCC", - "Identifiers": [ - "CCC.MLDE.TH01", - "CCC.TH01" - ] - } - ], - "SectionGuidelineMappings": [ - { - "ReferenceId": "NIST-CSF", - "Identifiers": [ - "PR.AC-4" - ] - }, - { - "ReferenceId": "CCM", - "Identifiers": [ - "IAM-12" - ] - }, - { - "ReferenceId": "ISO_27001", - "Identifiers": [ - "2013 A.9.1.2" - ] - }, - { - "ReferenceId": "NIST_800_53", - "Identifiers": [ - "AC-6" - ] - } - ] - } - ], - "Checks": [ - "sagemaker_notebook_instance_without_direct_internet_access_configured", - "sagemaker_training_jobs_network_isolation_enabled", - "sagemaker_models_network_isolation_enabled", - "sagemaker_training_jobs_vpc_settings_configured", - "sagemaker_notebook_instance_vpc_settings_configured", - "sagemaker_notebook_instance_encryption_enabled" - ] - }, - { - "Id": "CCC.Message.CN01.AR01", - "Description": "Attempt to publish a message without using a customer-managed encryption key\nand verify that the message is rejected or not stored.", - "Attributes": [ - { - "FamilyName": "Encryption", - "FamilyDescription": "TODO: Describe this control family", - "Section": "CCC.Message.CN01 Use Customer-Managed Encryption Keys (CMEK) for Messages", - "SubSection": "", - "SubSectionObjective": "Ensure that messages are encrypted using customer-managed encryption keys (CMEK)\nto provide enhanced control over encryption processes and keys, meeting compliance and security requirements.", - "Applicability": [ - "tlp-clear", - "tlp-green", - "tlp-amber", - "tlp-red" - ], - "Recommendation": "", - "SectionThreatMappings": [ - { - "ReferenceId": "CCC", - "Identifiers": [ - "CCC.TH01" - ] - } - ], - "SectionGuidelineMappings": [ - { - "ReferenceId": "NIST-CSF", - "Identifiers": [ - "PR.DS-1" - ] - }, - { - "ReferenceId": "NIST_800_53", - "Identifiers": [ - "SC-12", - "SC-13" - ] - } - ] - } - ], - "Checks": [ - "firehose_stream_encrypted_at_rest", - "kinesis_stream_encrypted_at_rest" - ] - }, { "Id": "CCC.Monitor.CN01.AR01", - "Description": "When an External Monitoring system exceeds the anticipated rate of monitoring checks then\nRate Limiting MUST be applied and an Audit Alert MUST be generated.", + "Description": "When an External Monitoring system exceeds the anticipated rate of monitoring checks then Rate Limiting MUST be applied and an Audit Alert MUST be generated.", "Attributes": [ { "FamilyName": "Logging & Monitoring", @@ -4769,7 +3032,7 @@ }, { "Id": "CCC.Monitor.CN02.AR01", - "Description": "When an Custom or User-Defined Metric starts to flood a collector, then a rate limit MUST be applied\nto reduce the network impact of traffic and an alert must triggered.", + "Description": "When an Custom or User-Defined Metric starts to flood a collector, then a rate limit MUST be applied to reduce the network impact of traffic and an alert must triggered.", "Attributes": [ { "FamilyName": "Logging & Monitoring", @@ -4828,14 +3091,14 @@ }, { "Id": "CCC.Monitor.CN03.AR01", - "Description": "When external systems have approved access to internal systems not normally available for public access\nthen they MUST be secured to prevent unauthorised access jumping through to the internal systems and\nonly allow access to specific internal services.", + "Description": "When external systems have approved access to internal systems not normally available for public access then they MUST be secured to prevent unauthorised access jumping through to the internal systems and only allow access to specific internal services.", "Attributes": [ { "FamilyName": "Identity and Access Management", "FamilyDescription": "Controls designed to prevent unauthorised access to monitoring features.", "Section": "CCC.Monitor.CN03 Access External Monitoring", "SubSection": "", - "SubSectionObjective": "Control access to Synthetic monitoring solutions using API keys or Certificate based authentication to\nensure they don't become an attack path, preventing monitoring systems from forging network requests to\ngain access to internal systems.", + "SubSectionObjective": "Control access to Synthetic monitoring solutions using API keys or Certificate based authentication to ensure they don't become an attack path, preventing monitoring systems from forging network requests to gain access to internal systems.", "Applicability": [ "tlp-clear", "tlp-green", @@ -4880,7 +3143,7 @@ }, { "Id": "CCC.Monitor.CN04.AR01", - "Description": "When monitoring dashboards display degraded services which may become potential targets then the\ndashboard MUST be protected from unauthorised access.", + "Description": "When monitoring dashboards display degraded services which may become potential targets then the dashboard MUST be protected from unauthorised access.", "Attributes": [ { "FamilyName": "Identity and Access Management", @@ -4930,7 +3193,7 @@ }, { "Id": "CCC.Monitor.CN05.AR01", - "Description": "When monitoring services have generated an alert, the service MUST ensure only authorised\nresponders silence or acknowledge the alert.", + "Description": "When monitoring services have generated an alert, the service MUST ensure only authorised responders silence or acknowledge the alert.", "Attributes": [ { "FamilyName": "Identity and Access Management", @@ -4988,7 +3251,7 @@ "FamilyDescription": "Controls designed to prevent unauthorised access to monitoring features.", "Section": "CCC.Monitor.CN06 Metrics pushed for authorised services only", "SubSection": "", - "SubSectionObjective": "Use IAM to control which types of metrics or traces can be pushed by different system to avoid a compromised\nsystem pushing fabricated metrics about a different service", + "SubSectionObjective": "Use IAM to control which types of metrics or traces can be pushed by different system to avoid a compromised system pushing fabricated metrics about a different service", "Applicability": [ "tlp-clear", "tlp-green", @@ -5030,189 +3293,16 @@ "cloudwatch_log_group_not_publicly_accessible" ] }, - { - "Id": "CCC.SecMgmt.CN01.AR01", - "Description": "Attempt to use an outdated version of a secret after its rotation period\nhas passed and verify that access is denied.", - "Attributes": [ - { - "FamilyName": "Data Protection", - "FamilyDescription": "TODO: Describe this control family", - "Section": "CCC.SecMgmt.CN01 Enforce Automatic Secret Rotation", - "SubSection": "", - "SubSectionObjective": "Ensure that secrets are automatically rotated on a defined schedule to\nreduce the risk of secret compromise and unauthorized access.", - "Applicability": [ - "tlp-red", - "tlp-amber" - ], - "Recommendation": "", - "SectionThreatMappings": [ - { - "ReferenceId": "CCC", - "Identifiers": [ - "CCC.TH01", - "CCC.TH14" - ] - } - ], - "SectionGuidelineMappings": [ - { - "ReferenceId": "NIST-CSF", - "Identifiers": [ - "PR.DS-6" - ] - }, - { - "ReferenceId": "NIST_800_53", - "Identifiers": [ - "SC-12", - "SC-28" - ] - } - ] - } - ], - "Checks": [] - }, - { - "Id": "CCC.SecMgmt.CN02.AR01", - "Description": "Attempt to retrieve a secret from an unauthorized region and verify that access is denied.", - "Attributes": [ - { - "FamilyName": "Data Protection", - "FamilyDescription": "TODO: Describe this control family", - "Section": "CCC.SecMgmt.CN02 Enforce Secret Replication Policies", - "SubSection": "", - "SubSectionObjective": "Ensure that secrets are replicated only to authorized locations as per\norganizational data residency and compliance requirements.", - "Applicability": [ - "tlp-red", - "tlp-amber" - ], - "Recommendation": "", - "SectionThreatMappings": [ - { - "ReferenceId": "CCC", - "Identifiers": [ - "CCC.TH03", - "CCC.TH04" - ] - } - ], - "SectionGuidelineMappings": [ - { - "ReferenceId": "NIST-CSF", - "Identifiers": [ - "PR.DS-5" - ] - }, - { - "ReferenceId": "NIST_800_53", - "Identifiers": [ - "AC-3", - "SC-7" - ] - } - ] - } - ], - "Checks": [] - }, - { - "Id": "CCC.SvlsComp.CN01.AR01", - "Description": "Attempt to access the serverless function over the public internet and verify that access is denied.", - "Attributes": [ - { - "FamilyName": "Network Security", - "FamilyDescription": "TODO: Describe this control family", - "Section": "CCC.SvlsComp.CN01 Enforce Use of Private Endpoints for Serverless Function", - "SubSection": "", - "SubSectionObjective": "Ensure that the serverless function is accessible only through a private endpoint,\nallowing it to communicate securely within a virtual private network and preventing\nunauthorized external access.", - "Applicability": [ - "tlp-red", - "tlp-amber" - ], - "Recommendation": "", - "SectionThreatMappings": [ - { - "ReferenceId": "CCC", - "Identifiers": [ - "CCC.TH01" - ] - } - ], - "SectionGuidelineMappings": [ - { - "ReferenceId": "NIST-CSF", - "Identifiers": [ - "PR.AC-5" - ] - }, - { - "ReferenceId": "NIST_800_53", - "Identifiers": [ - "SC-7", - "SC-8" - ] - } - ] - } - ], - "Checks": [ - "awslambda_function_url_public", - "awslambda_function_not_publicly_accessible", - "awslambda_function_inside_vpc" - ] - }, - { - "Id": "CCC.SvlsComp.CN02.AR01", - "Description": "Send requests to invoke the function up to the allowed threshold and confirm they\nare successful; then send additional requests exceeding the threshold from the same\nentity and verify that they are denied.", - "Attributes": [ - { - "FamilyName": "Availability", - "FamilyDescription": "TODO: Describe this control family", - "Section": "CCC.SvlsComp.CN02 Implement Function Invocation Rate Limits", - "SubSection": "", - "SubSectionObjective": "Ensure that function invocation is limited to a specified threshold from any single entity,\npreventing resource exhaustion and denial of service attacks.", - "Applicability": [ - "tlp-red", - "tlp-amber" - ], - "Recommendation": "", - "SectionThreatMappings": [ - { - "ReferenceId": "CCC", - "Identifiers": [ - "CCC.TH12" - ] - } - ], - "SectionGuidelineMappings": [ - { - "ReferenceId": "NIST-CSF", - "Identifiers": [ - "PR.DS-4" - ] - }, - { - "ReferenceId": "NIST_800_53", - "Identifiers": [ - "SC-5" - ] - } - ] - } - ], - "Checks": [] - }, { "Id": "CCC.VPC.CN01.AR01", - "Description": "When a subscription is created, the subscription MUST NOT\ncontain default network resources.", + "Description": "When a subscription is created, the subscription MUST NOT contain default network resources.", "Attributes": [ { "FamilyName": "Network Security", "FamilyDescription": "TODO: Describe this control family", "Section": "CCC.VPC.CN01 Restrict Default Network Creation", "SubSection": "", - "SubSectionObjective": "Restrict the automatic creation of default virtual networks and related\nresources during subscription initialization to avoid insecure default\nconfigurations and enforce custom network policies.", + "SubSectionObjective": "Restrict the automatic creation of default virtual networks and related resources during subscription initialization to avoid insecure default configurations and enforce custom network policies.", "Applicability": [ "tlp-amber", "tlp-red" @@ -5260,72 +3350,16 @@ "ec2_securitygroup_allow_ingress_from_internet_to_any_port" ] }, - { - "Id": "CCC.VPC.CN02.AR01", - "Description": "When a resource is created in a public subnet, that resource\nMUST NOT be assigned an external IP address by default.", - "Attributes": [ - { - "FamilyName": "Network Security", - "FamilyDescription": "TODO: Describe this control family", - "Section": "CCC.VPC.CN02 Limit Resource Creation in Public Subnet", - "SubSection": "", - "SubSectionObjective": "Restrict the creation of resources in the public subnet with\ndirect access to the internet to minimize attack surfaces.", - "Applicability": [ - "tlp-red" - ], - "Recommendation": "", - "SectionThreatMappings": [ - { - "ReferenceId": "CCC", - "Identifiers": [ - "CCC.VPC.TH02" - ] - } - ], - "SectionGuidelineMappings": [ - { - "ReferenceId": "NIST-CSF", - "Identifiers": [ - "PR.AC-3" - ] - }, - { - "ReferenceId": "CCM", - "Identifiers": [ - "SEF-05" - ] - }, - { - "ReferenceId": "ISO_27001", - "Identifiers": [ - "2013 A.13.1.1" - ] - }, - { - "ReferenceId": "NIST_800_53", - "Identifiers": [ - "AC-4" - ] - } - ] - } - ], - "Checks": [ - "vpc_subnet_no_public_ip_by_default", - "ec2_launch_template_no_public_ip", - "autoscaling_group_launch_configuration_no_public_ip" - ] - }, { "Id": "CCC.VPC.CN03.AR01", - "Description": "When a VPC peering connection is requested, the service MUST\nprevent connections from VPCs that are not explicitly\nallowed.", + "Description": "When a VPC peering connection is requested, the service MUST prevent connections from VPCs that are not explicitly allowed.", "Attributes": [ { "FamilyName": "Network Security", "FamilyDescription": "TODO: Describe this control family", "Section": "CCC.VPC.CN03 Restrict VPC Peering to Authorized Accounts", "SubSection": "", - "SubSectionObjective": "Ensure VPC peering connections are only established with explicitly\nauthorized destinations to limit network exposure and enforce boundary\ncontrols.", + "SubSectionObjective": "Ensure VPC peering connections are only established with explicitly authorized destinations to limit network exposure and enforce boundary controls.", "Applicability": [ "tlp-green", "tlp-amber", @@ -5374,14 +3408,14 @@ }, { "Id": "CCC.VPC.CN04.AR01", - "Description": "When any network traffic goes to or from an interface in the VPC,\nthe service MUST capture and log all relevant information.", + "Description": "When any network traffic goes to or from an interface in the VPC, the service MUST capture and log all relevant information.", "Attributes": [ { "FamilyName": "Network Security", "FamilyDescription": "TODO: Describe this control family", "Section": "CCC.VPC.CN04 Enforce VPC Flow Logs on VPCs", "SubSection": "", - "SubSectionObjective": "Ensure VPCs are configured with flow logs enabled to capture traffic\ninformation.", + "SubSectionObjective": "Ensure VPCs are configured with flow logs enabled to capture traffic information.", "Applicability": [ "tlp-amber", "tlp-red" @@ -5429,14 +3463,14 @@ }, { "Id": "CCC.Vector.CN01.AR01", - "Description": "When a vector embedding is submitted for indexing, the system MUST validate that it\nmatches expected schema, dimension, and format profiles.", + "Description": "When a vector embedding is submitted for indexing, the system MUST validate that it matches expected schema, dimension, and format profiles.", "Attributes": [ { "FamilyName": "Vector Indexing", "FamilyDescription": "Controls specific to the management and protection of vector embedding and index operations.", "Section": "CCC.Vector.CN01 Validate Embeddings Before Indexing", "SubSection": "", - "SubSectionObjective": "Ensure all incoming embeddings are structurally and statistically validated\nbefore indexing to prevent poisoning or corruption.", + "SubSectionObjective": "Ensure all incoming embeddings are structurally and statistically validated before indexing to prevent poisoning or corruption.", "Applicability": [ "tlp-clear", "tlp-green", @@ -5468,14 +3502,14 @@ }, { "Id": "CCC.Vector.CN02.AR01", - "Description": "When an index lifecycle event is triggered, the service MUST\nverify that the actor has explicit permissions for the operation type.", + "Description": "When an index lifecycle event is triggered, the service MUST verify that the actor has explicit permissions for the operation type.", "Attributes": [ { "FamilyName": "Vector Indexing", "FamilyDescription": "Controls specific to the management and protection of vector embedding and index operations.", "Section": "CCC.Vector.CN02 Enforce Role-Based Index Lifecycle Management", "SubSection": "", - "SubSectionObjective": "Restrict index lifecycle operations (create, delete, rollback) to privileged\nidentities using fine-grained access controls.", + "SubSectionObjective": "Restrict index lifecycle operations (create, delete, rollback) to privileged identities using fine-grained access controls.", "Applicability": [ "tlp-clear", "tlp-green", @@ -5519,14 +3553,14 @@ }, { "Id": "CCC.Vector.CN03.AR01", - "Description": "When a metadata filter is applied to a query, the service MUST\nverify the requester is authorized to access that field.", + "Description": "When a metadata filter is applied to a query, the service MUST verify the requester is authorized to access that field.", "Attributes": [ { "FamilyName": "Vector Indexing", "FamilyDescription": "Controls specific to the management and protection of vector embedding and index operations.", "Section": "CCC.Vector.CN03 Enforce Metadata-Level Access Controls", "SubSection": "", - "SubSectionObjective": "Apply access control policies to metadata fields used in filtering to\nprevent unauthorized exposure or inference.", + "SubSectionObjective": "Apply access control policies to metadata fields used in filtering to prevent unauthorized exposure or inference.", "Applicability": [ "tlp-amber", "tlp-red" @@ -5557,14 +3591,14 @@ }, { "Id": "CCC.Vector.CN04.AR01", - "Description": "When ingestion exceeds pre-defined thresholds, the service MUST\nthrottle or reject excess vector write operations.", + "Description": "When ingestion exceeds pre-defined thresholds, the service MUST throttle or reject excess vector write operations.", "Attributes": [ { "FamilyName": "Vector Indexing", "FamilyDescription": "Controls specific to the management and protection of vector embedding and index operations.", "Section": "CCC.Vector.CN04 Enforce Ingestion Quotas and Throttling", "SubSection": "", - "SubSectionObjective": "Prevent ingestion-based DoS or index pollution by\nrate-limiting vector submissions and enforcing quotas.", + "SubSectionObjective": "Prevent ingestion-based DoS or index pollution by rate-limiting vector submissions and enforcing quotas.", "Applicability": [ "tlp-green", "tlp-amber", @@ -5594,14 +3628,14 @@ }, { "Id": "CCC.Vector.CN05.AR01", - "Description": "When a rollback is attempted, the system MUST log\nthe action and verify rollback authorization.", + "Description": "When a rollback is attempted, the system MUST log the action and verify rollback authorization.", "Attributes": [ { "FamilyName": "Vector Indexing", "FamilyDescription": "Controls specific to the management and protection of vector embedding and index operations.", "Section": "CCC.Vector.CN05 Enforce Index Versioning with Rollback Protection", "SubSection": "", - "SubSectionObjective": "Ensure vector indexes are versioned and that rollback\noperations are authorized and auditable.", + "SubSectionObjective": "Ensure vector indexes are versioned and that rollback operations are authorized and auditable.", "Applicability": [ "tlp-amber", "tlp-red" @@ -5631,14 +3665,14 @@ }, { "Id": "CCC.Vector.CN06.AR01", - "Description": "When an embedding is submitted, the service MUST validate\nthat its format and dimensionality match allowed profiles.", + "Description": "When an embedding is submitted, the service MUST validate that its format and dimensionality match allowed profiles.", "Attributes": [ { "FamilyName": "Vector Indexing", "FamilyDescription": "Controls specific to the management and protection of vector embedding and index operations.", "Section": "CCC.Vector.CN06 Enforce Dimensional and Format Constraints", "SubSection": "", - "SubSectionObjective": "Reject embeddings that do not conform to expected model\nspecifications (dimensions, format, etc).", + "SubSectionObjective": "Reject embeddings that do not conform to expected model specifications (dimensions, format, etc).", "Applicability": [ "tlp-clear", "tlp-green", @@ -5669,14 +3703,14 @@ }, { "Id": "CCC.Vector.CN07.AR01", - "Description": "When a search request is issued, clients MUST be allowed\nto declare their requirement for exact vs approximate results.", + "Description": "When a search request is issued, clients MUST be allowed to declare their requirement for exact vs approximate results.", "Attributes": [ { "FamilyName": "Vector Indexing", "FamilyDescription": "Controls specific to the management and protection of vector embedding and index operations.", "Section": "CCC.Vector.CN07 Support Explicit ANN vs. Exact Search Configuration", "SubSection": "", - "SubSectionObjective": "Provide clients with the option to enforce exact-match\n(non-ANN) search where search fidelity is critical.", + "SubSectionObjective": "Provide clients with the option to enforce exact-match (non-ANN) search where search fidelity is critical.", "Applicability": [ "tlp-amber", "tlp-red" @@ -5697,20 +3731,20 @@ }, { "Id": "CCC.Core.CN01.AR01", - "Description": "When a port is exposed for non-SSH network traffic, all traffic\nMUST include a TLS handshake AND be encrypted using TLS 1.3 or\nhigher.", + "Description": "When a port is exposed for non-SSH network traffic, all traffic MUST include a TLS handshake AND be encrypted using TLS 1.3 or higher.", "Attributes": [ { "FamilyName": "Data", - "FamilyDescription": "The Data control family ensures the confidentiality, integrity,\navailability, and sovereignty of data across its lifecycle.\nThese controls govern how data is transmitted, stored,\nreplicated, and protected from unauthorized access, tampering,\nor exposure beyond defined trust perimeters.\n", + "FamilyDescription": "The Data control family ensures the confidentiality, integrity, availability, and sovereignty of data across its lifecycle. These controls govern how data is transmitted, stored, replicated, and protected from unauthorized access, tampering, or exposure beyond defined trust perimeters. ", "Section": "CCC.Core.CN01 Encrypt Data for Transmission", "SubSection": "", - "SubSectionObjective": "Ensure that all communications are encrypted in transit to protect\ndata integrity and confidentiality.", + "SubSectionObjective": "Ensure that all communications are encrypted in transit to protect data integrity and confidentiality.", "Applicability": [ "tlp-green", "tlp-amber", "tlp-red" ], - "Recommendation": "Most cloud services enable TLS 1.3 by default. Where it is not\nalready set, ensure that your services are configured or updated\naccordingly.\n", + "Recommendation": "Most cloud services enable TLS 1.3 by default. Where it is not already set, ensure that your services are configured or updated accordingly. ", "SectionThreatMappings": [ { "ReferenceId": "CCC", @@ -5765,21 +3799,21 @@ }, { "Id": "CCC.Core.CN01.AR02", - "Description": "When a port is exposed for SSH network traffic, all traffic MUST\ninclude a SSH handshake AND be encrypted using SSHv2 or higher.", + "Description": "When a port is exposed for SSH network traffic, all traffic MUST include a SSH handshake AND be encrypted using SSHv2 or higher.", "Attributes": [ { "FamilyName": "Data", - "FamilyDescription": "The Data control family ensures the confidentiality, integrity,\navailability, and sovereignty of data across its lifecycle.\nThese controls govern how data is transmitted, stored,\nreplicated, and protected from unauthorized access, tampering,\nor exposure beyond defined trust perimeters.\n", + "FamilyDescription": "The Data control family ensures the confidentiality, integrity, availability, and sovereignty of data across its lifecycle. These controls govern how data is transmitted, stored, replicated, and protected from unauthorized access, tampering, or exposure beyond defined trust perimeters. ", "Section": "CCC.Core.CN01 Encrypt Data for Transmission", "SubSection": "", - "SubSectionObjective": "Ensure that all communications are encrypted in transit to protect\ndata integrity and confidentiality.", + "SubSectionObjective": "Ensure that all communications are encrypted in transit to protect data integrity and confidentiality.", "Applicability": [ "tlp-clear", "tlp-green", "tlp-amber", "tlp-red" ], - "Recommendation": "Any time port 22 is exposed, ensure that it has a properly\nimplemented SSH server with SSHv2 enabled and configured with\nstrong ciphers.\n", + "Recommendation": "Any time port 22 is exposed, ensure that it has a properly implemented SSH server with SSHv2 enabled and configured with strong ciphers. ", "SectionThreatMappings": [ { "ReferenceId": "CCC", @@ -5829,20 +3863,20 @@ }, { "Id": "CCC.Core.CN01.AR03", - "Description": "When the service receives unencrypted traffic, \nthen it MUST either block the request or automatically\nredirect it to the secure equivalent.", + "Description": "When the service receives unencrypted traffic, then it MUST either block the request or automatically redirect it to the secure equivalent.", "Attributes": [ { "FamilyName": "Data", - "FamilyDescription": "The Data control family ensures the confidentiality, integrity,\navailability, and sovereignty of data across its lifecycle.\nThese controls govern how data is transmitted, stored,\nreplicated, and protected from unauthorized access, tampering,\nor exposure beyond defined trust perimeters.\n", + "FamilyDescription": "The Data control family ensures the confidentiality, integrity, availability, and sovereignty of data across its lifecycle. These controls govern how data is transmitted, stored, replicated, and protected from unauthorized access, tampering, or exposure beyond defined trust perimeters. ", "Section": "CCC.Core.CN01 Encrypt Data for Transmission", "SubSection": "", - "SubSectionObjective": "Ensure that all communications are encrypted in transit to protect\ndata integrity and confidentiality.", + "SubSectionObjective": "Ensure that all communications are encrypted in transit to protect data integrity and confidentiality.", "Applicability": [ "tlp-green", "tlp-amber", "tlp-red" ], - "Recommendation": "Review firewall, load balancer, and application configurations to\nensure insecure protocols such as HTTP, FTP, and Telnet are not\nexposed. Where possible, implement automatic redirection to secure\nprotocols such as HTTPS, SFTP, SSH, and regularly scan for\nprotocol drift.\n", + "Recommendation": "Review firewall, load balancer, and application configurations to ensure insecure protocols such as HTTP, FTP, and Telnet are not exposed. Where possible, implement automatic redirection to secure protocols such as HTTPS, SFTP, SSH, and regularly scan for protocol drift. ", "SectionThreatMappings": [ { "ReferenceId": "CCC", @@ -5896,21 +3930,21 @@ }, { "Id": "CCC.Core.CN01.AR07", - "Description": "When a port is exposed, the service MUST ensure that the protocol\nand service officially assigned to that port number by the IANA\nService Name and Transport Protocol Port Number Registry, and no\nother, is run on that port.", + "Description": "When a port is exposed, the service MUST ensure that the protocol and service officially assigned to that port number by the IANA Service Name and Transport Protocol Port Number Registry, and no other, is run on that port.", "Attributes": [ { "FamilyName": "Data", - "FamilyDescription": "The Data control family ensures the confidentiality, integrity,\navailability, and sovereignty of data across its lifecycle.\nThese controls govern how data is transmitted, stored,\nreplicated, and protected from unauthorized access, tampering,\nor exposure beyond defined trust perimeters.\n", + "FamilyDescription": "The Data control family ensures the confidentiality, integrity, availability, and sovereignty of data across its lifecycle. These controls govern how data is transmitted, stored, replicated, and protected from unauthorized access, tampering, or exposure beyond defined trust perimeters. ", "Section": "CCC.Core.CN01 Encrypt Data for Transmission", "SubSection": "", - "SubSectionObjective": "Ensure that all communications are encrypted in transit to protect\ndata integrity and confidentiality.", + "SubSectionObjective": "Ensure that all communications are encrypted in transit to protect data integrity and confidentiality.", "Applicability": [ "tlp-clear", "tlp-green", "tlp-amber", "tlp-red" ], - "Recommendation": "Reference the IANA Service Name and Transport Protocol Port Number\nRegistry for more information about correct protocol-to-port\nassignments. Avoid running non-standard services on well-known\nports.\n", + "Recommendation": "Reference the IANA Service Name and Transport Protocol Port Number Registry for more information about correct protocol-to-port assignments. Avoid running non-standard services on well-known ports. ", "SectionThreatMappings": [ { "ReferenceId": "CCC", @@ -5964,19 +3998,19 @@ }, { "Id": "CCC.Core.CN01.AR08", - "Description": "When a service transmits data using TLS, mutual TLS (mTLS) MUST be\nimplemented to require both client and server certificate\nauthentication for all connections.", + "Description": "When a service transmits data using TLS, mutual TLS (mTLS) MUST be implemented to require both client and server certificate authentication for all connections.", "Attributes": [ { "FamilyName": "Data", - "FamilyDescription": "The Data control family ensures the confidentiality, integrity,\navailability, and sovereignty of data across its lifecycle.\nThese controls govern how data is transmitted, stored,\nreplicated, and protected from unauthorized access, tampering,\nor exposure beyond defined trust perimeters.\n", + "FamilyDescription": "The Data control family ensures the confidentiality, integrity, availability, and sovereignty of data across its lifecycle. These controls govern how data is transmitted, stored, replicated, and protected from unauthorized access, tampering, or exposure beyond defined trust perimeters. ", "Section": "CCC.Core.CN01 Encrypt Data for Transmission", "SubSection": "", - "SubSectionObjective": "Ensure that all communications are encrypted in transit to protect\ndata integrity and confidentiality.", + "SubSectionObjective": "Ensure that all communications are encrypted in transit to protect data integrity and confidentiality.", "Applicability": [ "tlp-amber", "tlp-red" ], - "Recommendation": "Configure mTLS for all endpoints that process or transmit\nsensitive data. Ensure both client and server certificates are\nvalidated and managed securely. Regularly review certificate\nauthorities and automate certificate rotation where possible.\n", + "Recommendation": "Configure mTLS for all endpoints that process or transmit sensitive data. Ensure both client and server certificates are validated and managed securely. Regularly review certificate authorities and automate certificate rotation where possible. ", "SectionThreatMappings": [ { "ReferenceId": "CCC", @@ -6035,21 +4069,21 @@ }, { "Id": "CCC.Core.CN13.AR01", - "Description": "When a port is exposed that uses certificate-based encryption,\nthe service MUST only use valid, unexpired certificates issued by\na trusted certificate authority.", + "Description": "When a port is exposed that uses certificate-based encryption, the service MUST only use valid, unexpired certificates issued by a trusted certificate authority.", "Attributes": [ { "FamilyName": "Data", - "FamilyDescription": "The Data control family ensures the confidentiality, integrity,\navailability, and sovereignty of data across its lifecycle.\nThese controls govern how data is transmitted, stored,\nreplicated, and protected from unauthorized access, tampering,\nor exposure beyond defined trust perimeters.\n", + "FamilyDescription": "The Data control family ensures the confidentiality, integrity, availability, and sovereignty of data across its lifecycle. These controls govern how data is transmitted, stored, replicated, and protected from unauthorized access, tampering, or exposure beyond defined trust perimeters. ", "Section": "CCC.Core.CN13 Minimize Lifetime of Encryption and Authentication Certificates", "SubSection": "", - "SubSectionObjective": "Ensure that encryption and authentication certificates have a limited\nlifetime to reduce the risk of compromise and ensure the use of\nup-to-date security practices.", + "SubSectionObjective": "Ensure that encryption and authentication certificates have a limited lifetime to reduce the risk of compromise and ensure the use of up-to-date security practices.", "Applicability": [ "tlp-clear", "tlp-green", "tlp-amber", "tlp-red" ], - "Recommendation": "Track certificate expiration dates and automate certificate\nrenewal where possible. Use certificate management tools to ensure\nonly certificates from trusted authorities are deployed.\n", + "Recommendation": "Track certificate expiration dates and automate certificate renewal where possible. Use certificate management tools to ensure only certificates from trusted authorities are deployed. ", "SectionThreatMappings": [ { "ReferenceId": "CCC", @@ -6069,18 +4103,18 @@ }, { "Id": "CCC.Core.CN13.AR02", - "Description": "When a port is exposed that uses certificate-based encryption,\nthe service MUST rotate active certificates within 180 days of\nissuance.", + "Description": "When a port is exposed that uses certificate-based encryption, the service MUST rotate active certificates within 180 days of issuance.", "Attributes": [ { "FamilyName": "Data", - "FamilyDescription": "The Data control family ensures the confidentiality, integrity,\navailability, and sovereignty of data across its lifecycle.\nThese controls govern how data is transmitted, stored,\nreplicated, and protected from unauthorized access, tampering,\nor exposure beyond defined trust perimeters.\n", + "FamilyDescription": "The Data control family ensures the confidentiality, integrity, availability, and sovereignty of data across its lifecycle. These controls govern how data is transmitted, stored, replicated, and protected from unauthorized access, tampering, or exposure beyond defined trust perimeters. ", "Section": "CCC.Core.CN13 Minimize Lifetime of Encryption and Authentication Certificates", "SubSection": "", - "SubSectionObjective": "Ensure that encryption and authentication certificates have a limited\nlifetime to reduce the risk of compromise and ensure the use of\nup-to-date security practices.", + "SubSectionObjective": "Ensure that encryption and authentication certificates have a limited lifetime to reduce the risk of compromise and ensure the use of up-to-date security practices.", "Applicability": [ "tlp-amber" ], - "Recommendation": "Track certificate expiration dates and automate certificate\nrenewal where possible. Use certificate management tools to ensure\nonly certificates from trusted authorities are deployed.\n", + "Recommendation": "Track certificate expiration dates and automate certificate renewal where possible. Use certificate management tools to ensure only certificates from trusted authorities are deployed. ", "SectionThreatMappings": [ { "ReferenceId": "CCC", @@ -6098,18 +4132,18 @@ }, { "Id": "CCC.Core.CN13.AR03", - "Description": "When a port is exposed that uses certificate-based encryption,\nthe service MUST rotate active certificates within 90 days of\nissuance.", + "Description": "When a port is exposed that uses certificate-based encryption, the service MUST rotate active certificates within 90 days of issuance.", "Attributes": [ { "FamilyName": "Data", - "FamilyDescription": "The Data control family ensures the confidentiality, integrity,\navailability, and sovereignty of data across its lifecycle.\nThese controls govern how data is transmitted, stored,\nreplicated, and protected from unauthorized access, tampering,\nor exposure beyond defined trust perimeters.\n", + "FamilyDescription": "The Data control family ensures the confidentiality, integrity, availability, and sovereignty of data across its lifecycle. These controls govern how data is transmitted, stored, replicated, and protected from unauthorized access, tampering, or exposure beyond defined trust perimeters. ", "Section": "CCC.Core.CN13 Minimize Lifetime of Encryption and Authentication Certificates", "SubSection": "", - "SubSectionObjective": "Ensure that encryption and authentication certificates have a limited\nlifetime to reduce the risk of compromise and ensure the use of\nup-to-date security practices.", + "SubSectionObjective": "Ensure that encryption and authentication certificates have a limited lifetime to reduce the risk of compromise and ensure the use of up-to-date security practices.", "Applicability": [ "tlp-red" ], - "Recommendation": "Track certificate expiration dates and automate certificate\nrenewal where possible. Use certificate management tools to ensure\nonly certificates from trusted authorities are deployed.\n", + "Recommendation": "Track certificate expiration dates and automate certificate renewal where possible. Use certificate management tools to ensure only certificates from trusted authorities are deployed. ", "SectionThreatMappings": [ { "ReferenceId": "CCC", @@ -6127,21 +4161,21 @@ }, { "Id": "CCC.Core.CN06.AR01", - "Description": "When the service is running, its region and availability zone MUST\nbe included in a list of explicitly trusted or approved locations\nwithin the trust perimeter.", + "Description": "When the service is running, its region and availability zone MUST be included in a list of explicitly trusted or approved locations within the trust perimeter.", "Attributes": [ { "FamilyName": "Data", - "FamilyDescription": "The Data control family ensures the confidentiality, integrity,\navailability, and sovereignty of data across its lifecycle.\nThese controls govern how data is transmitted, stored,\nreplicated, and protected from unauthorized access, tampering,\nor exposure beyond defined trust perimeters.\n", + "FamilyDescription": "The Data control family ensures the confidentiality, integrity, availability, and sovereignty of data across its lifecycle. These controls govern how data is transmitted, stored, replicated, and protected from unauthorized access, tampering, or exposure beyond defined trust perimeters. ", "Section": "CCC.Core.CN06 Restrict Deployments to Trust Perimeter", "SubSection": "", - "SubSectionObjective": "Ensure that the service and its child resources are only deployed on\ninfrastructure in locations that are explicitly included within a\ndefined trust perimeter.", + "SubSectionObjective": "Ensure that the service and its child resources are only deployed on infrastructure in locations that are explicitly included within a defined trust perimeter.", "Applicability": [ "tlp-clear", "tlp-green", "tlp-amber", "tlp-red" ], - "Recommendation": "Maintain an up-to-date list of trusted and approved regions based\non organizational policies. Validate the service's deployment\nlocation is included in this list.\n", + "Recommendation": "Maintain an up-to-date list of trusted and approved regions based on organizational policies. Validate the service's deployment location is included in this list. ", "SectionThreatMappings": [ { "ReferenceId": "CCC", @@ -6186,21 +4220,21 @@ }, { "Id": "CCC.Core.CN06.AR02", - "Description": "When a child resource is deployed, its region and availability\nzone MUST be included in a list of explicitly trusted or approved\nlocations within the trust perimeter.", + "Description": "When a child resource is deployed, its region and availability zone MUST be included in a list of explicitly trusted or approved locations within the trust perimeter.", "Attributes": [ { "FamilyName": "Data", - "FamilyDescription": "The Data control family ensures the confidentiality, integrity,\navailability, and sovereignty of data across its lifecycle.\nThese controls govern how data is transmitted, stored,\nreplicated, and protected from unauthorized access, tampering,\nor exposure beyond defined trust perimeters.\n", + "FamilyDescription": "The Data control family ensures the confidentiality, integrity, availability, and sovereignty of data across its lifecycle. These controls govern how data is transmitted, stored, replicated, and protected from unauthorized access, tampering, or exposure beyond defined trust perimeters. ", "Section": "CCC.Core.CN06 Restrict Deployments to Trust Perimeter", "SubSection": "", - "SubSectionObjective": "Ensure that the service and its child resources are only deployed on\ninfrastructure in locations that are explicitly included within a\ndefined trust perimeter.", + "SubSectionObjective": "Ensure that the service and its child resources are only deployed on infrastructure in locations that are explicitly included within a defined trust perimeter.", "Applicability": [ "tlp-clear", "tlp-green", "tlp-amber", "tlp-red" ], - "Recommendation": "Maintain an up-to-date list of trusted and approved regions based\non organizational policies. Validate that child resources can only\nbe deployed to locations included in this list.\n", + "Recommendation": "Maintain an up-to-date list of trusted and approved regions based on organizational policies. Validate that child resources can only be deployed to locations included in this list. ", "SectionThreatMappings": [ { "ReferenceId": "CCC", @@ -6245,20 +4279,20 @@ }, { "Id": "CCC.Core.CN08.AR01", - "Description": "When data is created or modified, the data MUST have a complete\nand recoverable duplicate that is stored in a physically separate\ndata center.", + "Description": "When data is created or modified, the data MUST have a complete and recoverable duplicate that is stored in a physically separate data center.", "Attributes": [ { "FamilyName": "Data", - "FamilyDescription": "The Data control family ensures the confidentiality, integrity,\navailability, and sovereignty of data across its lifecycle.\nThese controls govern how data is transmitted, stored,\nreplicated, and protected from unauthorized access, tampering,\nor exposure beyond defined trust perimeters.\n", + "FamilyDescription": "The Data control family ensures the confidentiality, integrity, availability, and sovereignty of data across its lifecycle. These controls govern how data is transmitted, stored, replicated, and protected from unauthorized access, tampering, or exposure beyond defined trust perimeters. ", "Section": "CCC.Core.CN08 Replicate Data to Multiple Locations", "SubSection": "", - "SubSectionObjective": "Ensure that data is replicated across multiple physical locations to\nprotect against data loss due to hardware failures, natural disasters,\nor other catastrophic events.", + "SubSectionObjective": "Ensure that data is replicated across multiple physical locations to protect against data loss due to hardware failures, natural disasters, or other catastrophic events.", "Applicability": [ "tlp-green", "tlp-amber", "tlp-red" ], - "Recommendation": "Implement automated data replication processes to ensure that\ndata is consistently duplicated in another region or availability\nzone. Regularly test data recovery from the replicated location to\nensure integrity and availability.\n", + "Recommendation": "Implement automated data replication processes to ensure that data is consistently duplicated in another region or availability zone. Regularly test data recovery from the replicated location to ensure integrity and availability. ", "SectionThreatMappings": [ { "ReferenceId": "CCC", @@ -6305,14 +4339,14 @@ }, { "Id": "CCC.Core.CN08.AR02", - "Description": "When data is replicated into a second location, the service MUST\nbe able to accurately represent the replication locations,\nreplication status, and data synchronization status.", + "Description": "When data is replicated into a second location, the service MUST be able to accurately represent the replication locations, replication status, and data synchronization status.", "Attributes": [ { "FamilyName": "Data", - "FamilyDescription": "The Data control family ensures the confidentiality, integrity,\navailability, and sovereignty of data across its lifecycle.\nThese controls govern how data is transmitted, stored,\nreplicated, and protected from unauthorized access, tampering,\nor exposure beyond defined trust perimeters.\n", + "FamilyDescription": "The Data control family ensures the confidentiality, integrity, availability, and sovereignty of data across its lifecycle. These controls govern how data is transmitted, stored, replicated, and protected from unauthorized access, tampering, or exposure beyond defined trust perimeters. ", "Section": "CCC.Core.CN08 Replicate Data to Multiple Locations", "SubSection": "", - "SubSectionObjective": "Ensure that data is replicated across multiple physical locations to\nprotect against data loss due to hardware failures, natural disasters,\nor other catastrophic events.", + "SubSectionObjective": "Ensure that data is replicated across multiple physical locations to protect against data loss due to hardware failures, natural disasters, or other catastrophic events.", "Applicability": [ "tlp-green", "tlp-amber", @@ -6358,14 +4392,14 @@ }, { "Id": "CCC.Core.CN09.AR01", - "Description": "When the service is operational, its logs and any child resource\nlogs MUST NOT be accessible from the resource they record access\nto.", + "Description": "When the service is operational, its logs and any child resource logs MUST NOT be accessible from the resource they record access to.", "Attributes": [ { "FamilyName": "Data", - "FamilyDescription": "The Data control family ensures the confidentiality, integrity,\navailability, and sovereignty of data across its lifecycle.\nThese controls govern how data is transmitted, stored,\nreplicated, and protected from unauthorized access, tampering,\nor exposure beyond defined trust perimeters.\n", + "FamilyDescription": "The Data control family ensures the confidentiality, integrity, availability, and sovereignty of data across its lifecycle. These controls govern how data is transmitted, stored, replicated, and protected from unauthorized access, tampering, or exposure beyond defined trust perimeters. ", "Section": "CCC.Core.CN09 Ensure Integrity of Access Logs", "SubSection": "", - "SubSectionObjective": "Ensure that access logs are always recorded to an external location\nthat cannot be manipulated from the context of the service(s) it\ncontains logs for.", + "SubSectionObjective": "Ensure that access logs are always recorded to an external location that cannot be manipulated from the context of the service(s) it contains logs for.", "Applicability": [ "tlp-clear", "tlp-green", @@ -6420,21 +4454,21 @@ }, { "Id": "CCC.Core.CN09.AR02", - "Description": "When the service is operational, disabling the logs for the service\nor its child resources MUST NOT be possible without also disabling\nthe corresponding resource.", + "Description": "When the service is operational, disabling the logs for the service or its child resources MUST NOT be possible without also disabling the corresponding resource.", "Attributes": [ { "FamilyName": "Data", - "FamilyDescription": "The Data control family ensures the confidentiality, integrity,\navailability, and sovereignty of data across its lifecycle.\nThese controls govern how data is transmitted, stored,\nreplicated, and protected from unauthorized access, tampering,\nor exposure beyond defined trust perimeters.\n", + "FamilyDescription": "The Data control family ensures the confidentiality, integrity, availability, and sovereignty of data across its lifecycle. These controls govern how data is transmitted, stored, replicated, and protected from unauthorized access, tampering, or exposure beyond defined trust perimeters. ", "Section": "CCC.Core.CN09 Ensure Integrity of Access Logs", "SubSection": "", - "SubSectionObjective": "Ensure that access logs are always recorded to an external location\nthat cannot be manipulated from the context of the service(s) it\ncontains logs for.", + "SubSectionObjective": "Ensure that access logs are always recorded to an external location that cannot be manipulated from the context of the service(s) it contains logs for.", "Applicability": [ "tlp-clear", "tlp-green", "tlp-amber", "tlp-red" ], - "Recommendation": "No normal business operations should disable\nlogs, as this could indicate an attempt to cover up unauthorized\naccess. Ensure that logging mechanisms are tightly integrated with\nservice operations, so that logging cannot be disabled without\nstopping the service itself.\n", + "Recommendation": "No normal business operations should disable logs, as this could indicate an attempt to cover up unauthorized access. Ensure that logging mechanisms are tightly integrated with service operations, so that logging cannot be disabled without stopping the service itself. ", "SectionThreatMappings": [ { "ReferenceId": "CCC", @@ -6486,19 +4520,19 @@ }, { "Id": "CCC.Core.CN09.AR03", - "Description": "When the service is operational, any attempt to redirect logs for\nthe service or its child resources MUST NOT be possible without\nhalting operation of the corresponding resource and publishing\ncorresponding events to monitored channels.", + "Description": "When the service is operational, any attempt to redirect logs for the service or its child resources MUST NOT be possible without halting operation of the corresponding resource and publishing corresponding events to monitored channels.", "Attributes": [ { "FamilyName": "Data", - "FamilyDescription": "The Data control family ensures the confidentiality, integrity,\navailability, and sovereignty of data across its lifecycle.\nThese controls govern how data is transmitted, stored,\nreplicated, and protected from unauthorized access, tampering,\nor exposure beyond defined trust perimeters.\n", + "FamilyDescription": "The Data control family ensures the confidentiality, integrity, availability, and sovereignty of data across its lifecycle. These controls govern how data is transmitted, stored, replicated, and protected from unauthorized access, tampering, or exposure beyond defined trust perimeters. ", "Section": "CCC.Core.CN09 Ensure Integrity of Access Logs", "SubSection": "", - "SubSectionObjective": "Ensure that access logs are always recorded to an external location\nthat cannot be manipulated from the context of the service(s) it\ncontains logs for.", + "SubSectionObjective": "Ensure that access logs are always recorded to an external location that cannot be manipulated from the context of the service(s) it contains logs for.", "Applicability": [ "tlp-amber", "tlp-red" ], - "Recommendation": "No normal business operations should result in the redirection of\nlogs, as this could indicate an attempt to cover up unauthorized\naccess. Ensure that logging configurations are immutable during\nservice operation so that any changes require stopping the service\nand publishing corresponding events to monitored channels.\n", + "Recommendation": "No normal business operations should result in the redirection of logs, as this could indicate an attempt to cover up unauthorized access. Ensure that logging configurations are immutable during service operation so that any changes require stopping the service and publishing corresponding events to monitored channels. ", "SectionThreatMappings": [ { "ReferenceId": "CCC", @@ -6554,14 +4588,14 @@ }, { "Id": "CCC.Core.CN10.AR01", - "Description": "When data is replicated, the service MUST ensure that replication\nonly occurs to destinations that are explicitly included within\nthe defined trust perimeter.", + "Description": "When data is replicated, the service MUST ensure that replication only occurs to destinations that are explicitly included within the defined trust perimeter.", "Attributes": [ { "FamilyName": "Data", - "FamilyDescription": "The Data control family ensures the confidentiality, integrity,\navailability, and sovereignty of data across its lifecycle.\nThese controls govern how data is transmitted, stored,\nreplicated, and protected from unauthorized access, tampering,\nor exposure beyond defined trust perimeters.\n", + "FamilyDescription": "The Data control family ensures the confidentiality, integrity, availability, and sovereignty of data across its lifecycle. These controls govern how data is transmitted, stored, replicated, and protected from unauthorized access, tampering, or exposure beyond defined trust perimeters. ", "Section": "CCC.Core.CN10 Restrict Data Replication to Trust Perimeter", "SubSection": "", - "SubSectionObjective": "Ensure that data is only replicated on infrastructure in locations\nthat are explicitly included within a defined trust perimeter.", + "SubSectionObjective": "Ensure that data is only replicated on infrastructure in locations that are explicitly included within a defined trust perimeter.", "Applicability": [ "tlp-green", "tlp-amber", @@ -6607,14 +4641,14 @@ }, { "Id": "CCC.Core.CN02.AR01", - "Description": "When data is stored, it MUST be encrypted using the latest\nindustry-standard encryption methods.", + "Description": "When data is stored, it MUST be encrypted using the latest industry-standard encryption methods.", "Attributes": [ { "FamilyName": "Data", - "FamilyDescription": "The Data control family ensures the confidentiality, integrity,\navailability, and sovereignty of data across its lifecycle.\nThese controls govern how data is transmitted, stored,\nreplicated, and protected from unauthorized access, tampering,\nor exposure beyond defined trust perimeters.\n", + "FamilyDescription": "The Data control family ensures the confidentiality, integrity, availability, and sovereignty of data across its lifecycle. These controls govern how data is transmitted, stored, replicated, and protected from unauthorized access, tampering, or exposure beyond defined trust perimeters. ", "Section": "CCC.Core.CN02 Encrypt Data for Storage", "SubSection": "", - "SubSectionObjective": "Ensure that all data stored is encrypted at rest using strong\nencryption algorithms.", + "SubSectionObjective": "Ensure that all data stored is encrypted at rest using strong encryption algorithms.", "Applicability": [ "tlp-green", "tlp-amber", @@ -6676,14 +4710,14 @@ }, { "Id": "CCC.Core.CN11.AR01", - "Description": "When encryption keys are used, the service MUST verify that\nall encryption keys use the latest industry-standard cryptographic\nalgorithms.", + "Description": "When encryption keys are used, the service MUST verify that all encryption keys use the latest industry-standard cryptographic algorithms.", "Attributes": [ { "FamilyName": "Data", - "FamilyDescription": "The Data control family ensures the confidentiality, integrity,\navailability, and sovereignty of data across its lifecycle.\nThese controls govern how data is transmitted, stored,\nreplicated, and protected from unauthorized access, tampering,\nor exposure beyond defined trust perimeters.\n", + "FamilyDescription": "The Data control family ensures the confidentiality, integrity, availability, and sovereignty of data across its lifecycle. These controls govern how data is transmitted, stored, replicated, and protected from unauthorized access, tampering, or exposure beyond defined trust perimeters. ", "Section": "CCC.Core.CN11 Protect Encryption Keys", "SubSection": "", - "SubSectionObjective": "Ensure that encryption keys are managed securely by enforcing\nthe use of approved algorithms, regular key rotation, and\ncustomer-managed encryption keys (CMEKs).", + "SubSectionObjective": "Ensure that encryption keys are managed securely by enforcing the use of approved algorithms, regular key rotation, and customer-managed encryption keys (CMEKs).", "Applicability": [ "tlp-amber", "tlp-red" @@ -6737,14 +4771,14 @@ }, { "Id": "CCC.Core.CN11.AR02", - "Description": "When encryption keys are used, the service MUST rotate active keys\nwithin 180 days of issuance.", + "Description": "When encryption keys are used, the service MUST rotate active keys within 180 days of issuance.", "Attributes": [ { "FamilyName": "Data", - "FamilyDescription": "The Data control family ensures the confidentiality, integrity,\navailability, and sovereignty of data across its lifecycle.\nThese controls govern how data is transmitted, stored,\nreplicated, and protected from unauthorized access, tampering,\nor exposure beyond defined trust perimeters.\n", + "FamilyDescription": "The Data control family ensures the confidentiality, integrity, availability, and sovereignty of data across its lifecycle. These controls govern how data is transmitted, stored, replicated, and protected from unauthorized access, tampering, or exposure beyond defined trust perimeters. ", "Section": "CCC.Core.CN11 Protect Encryption Keys", "SubSection": "", - "SubSectionObjective": "Ensure that encryption keys are managed securely by enforcing\nthe use of approved algorithms, regular key rotation, and\ncustomer-managed encryption keys (CMEKs).", + "SubSectionObjective": "Ensure that encryption keys are managed securely by enforcing the use of approved algorithms, regular key rotation, and customer-managed encryption keys (CMEKs).", "Applicability": [ "tlp-amber" ], @@ -6797,14 +4831,14 @@ }, { "Id": "CCC.Core.CN11.AR03", - "Description": "When encrypting data, the service MUST verify that\ncustomer-managed encryption keys (CMEKs) are used.", + "Description": "When encrypting data, the service MUST verify that customer-managed encryption keys (CMEKs) are used.", "Attributes": [ { "FamilyName": "Data", - "FamilyDescription": "The Data control family ensures the confidentiality, integrity,\navailability, and sovereignty of data across its lifecycle.\nThese controls govern how data is transmitted, stored,\nreplicated, and protected from unauthorized access, tampering,\nor exposure beyond defined trust perimeters.\n", + "FamilyDescription": "The Data control family ensures the confidentiality, integrity, availability, and sovereignty of data across its lifecycle. These controls govern how data is transmitted, stored, replicated, and protected from unauthorized access, tampering, or exposure beyond defined trust perimeters. ", "Section": "", "SubSection": "CCC.Core.CN11 Protect Encryption Keys", - "SubSectionObjective": "Ensure that encryption keys are managed securely by enforcing\nthe use of approved algorithms, regular key rotation, and\ncustomer-managed encryption keys (CMEKs).", + "SubSectionObjective": "Ensure that encryption keys are managed securely by enforcing the use of approved algorithms, regular key rotation, and customer-managed encryption keys (CMEKs).", "Applicability": [ "tlp-amber", "tlp-red" @@ -6858,14 +4892,14 @@ }, { "Id": "CCC.Core.CN11.AR04", - "Description": "When encryption keys are accessed, the service MUST verify that\naccess to encryption keys is restricted to authorized personnel\nand services, following the principle of least privilege.", + "Description": "When encryption keys are accessed, the service MUST verify that access to encryption keys is restricted to authorized personnel and services, following the principle of least privilege.", "Attributes": [ { "FamilyName": "Data", - "FamilyDescription": "The Data control family ensures the confidentiality, integrity,\navailability, and sovereignty of data across its lifecycle.\nThese controls govern how data is transmitted, stored,\nreplicated, and protected from unauthorized access, tampering,\nor exposure beyond defined trust perimeters.\n", + "FamilyDescription": "The Data control family ensures the confidentiality, integrity, availability, and sovereignty of data across its lifecycle. These controls govern how data is transmitted, stored, replicated, and protected from unauthorized access, tampering, or exposure beyond defined trust perimeters. ", "Section": "CCC.Core.CN11 Protect Encryption Keys", "SubSection": "", - "SubSectionObjective": "Ensure that encryption keys are managed securely by enforcing\nthe use of approved algorithms, regular key rotation, and\ncustomer-managed encryption keys (CMEKs).", + "SubSectionObjective": "Ensure that encryption keys are managed securely by enforcing the use of approved algorithms, regular key rotation, and customer-managed encryption keys (CMEKs).", "Applicability": [ "tlp-clear", "tlp-green", @@ -6921,14 +4955,14 @@ }, { "Id": "CCC.Core.CN11.AR05", - "Description": "When encryption keys are used, the service MUST rotate active keys\nwithin 365 days of issuance.", + "Description": "When encryption keys are used, the service MUST rotate active keys within 365 days of issuance.", "Attributes": [ { "FamilyName": "Data", - "FamilyDescription": "The Data control family ensures the confidentiality, integrity,\navailability, and sovereignty of data across its lifecycle.\nThese controls govern how data is transmitted, stored,\nreplicated, and protected from unauthorized access, tampering,\nor exposure beyond defined trust perimeters.\n", + "FamilyDescription": "The Data control family ensures the confidentiality, integrity, availability, and sovereignty of data across its lifecycle. These controls govern how data is transmitted, stored, replicated, and protected from unauthorized access, tampering, or exposure beyond defined trust perimeters. ", "Section": "CCC.Core.CN11 Protect Encryption Keys", "SubSection": "", - "SubSectionObjective": "Ensure that encryption keys are managed securely by enforcing\nthe use of approved algorithms, regular key rotation, and\ncustomer-managed encryption keys (CMEKs).", + "SubSectionObjective": "Ensure that encryption keys are managed securely by enforcing the use of approved algorithms, regular key rotation, and customer-managed encryption keys (CMEKs).", "Applicability": [ "tlp-clear", "tlp-green" @@ -6980,14 +5014,14 @@ }, { "Id": "CCC.Core.CN11.AR06", - "Description": "When encryption keys are used, the service MUST rotate active keys\nwithin 90 days of issuance.", + "Description": "When encryption keys are used, the service MUST rotate active keys within 90 days of issuance.", "Attributes": [ { "FamilyName": "Data", - "FamilyDescription": "The Data control family ensures the confidentiality, integrity,\navailability, and sovereignty of data across its lifecycle.\nThese controls govern how data is transmitted, stored,\nreplicated, and protected from unauthorized access, tampering,\nor exposure beyond defined trust perimeters.\n", + "FamilyDescription": "The Data control family ensures the confidentiality, integrity, availability, and sovereignty of data across its lifecycle. These controls govern how data is transmitted, stored, replicated, and protected from unauthorized access, tampering, or exposure beyond defined trust perimeters. ", "Section": "CCC.Core.CN11 Protect Encryption Keys", "SubSection": "", - "SubSectionObjective": "Ensure that encryption keys are managed securely by enforcing\nthe use of approved algorithms, regular key rotation, and\ncustomer-managed encryption keys (CMEKs).", + "SubSectionObjective": "Ensure that encryption keys are managed securely by enforcing the use of approved algorithms, regular key rotation, and customer-managed encryption keys (CMEKs).", "Applicability": [ "tlp-red" ], @@ -7037,21 +5071,21 @@ }, { "Id": "CCC.Core.CN14.AR01", - "Description": "When backups are created for disaster recovery purposes, the\nstorage mechanism MUST NOT allow modification or deletion\nwithin 30 days of creation.", + "Description": "When backups are created for disaster recovery purposes, the storage mechanism MUST NOT allow modification or deletion within 30 days of creation.", "Attributes": [ { "FamilyName": "Data", - "FamilyDescription": "The Data control family ensures the confidentiality, integrity,\navailability, and sovereignty of data across its lifecycle.\nThese controls govern how data is transmitted, stored,\nreplicated, and protected from unauthorized access, tampering,\nor exposure beyond defined trust perimeters.\n", + "FamilyDescription": "The Data control family ensures the confidentiality, integrity, availability, and sovereignty of data across its lifecycle. These controls govern how data is transmitted, stored, replicated, and protected from unauthorized access, tampering, or exposure beyond defined trust perimeters. ", "Section": "CCC.Core.CN14 Maintain Recent Backups", "SubSection": "", - "SubSectionObjective": "Ensure that all backups used for disaster recovery are recent and\nsubject to a retention policy that limits deletion.", + "SubSectionObjective": "Ensure that all backups used for disaster recovery are recent and subject to a retention policy that limits deletion.", "Applicability": [ "tlp-clear", "tlp-green", "tlp-amber", "tlp-red" ], - "Recommendation": "Use immutable storage solutions where possible. Implement backup\nretention policies that enforce a minimum retention period of 30\ndays.\n", + "Recommendation": "Use immutable storage solutions where possible. Implement backup retention policies that enforce a minimum retention period of 30 days. ", "SectionThreatMappings": [ { "ReferenceId": "CCC", @@ -7069,20 +5103,20 @@ }, { "Id": "CCC.Core.CN14.AR02", - "Description": "When backups are created for disaster recovery purposes, the\nmost recent backup MUST have a creation date within the past\n30 days.", + "Description": "When backups are created for disaster recovery purposes, the most recent backup MUST have a creation date within the past 30 days.", "Attributes": [ { "FamilyName": "Data", - "FamilyDescription": "The Data control family ensures the confidentiality, integrity,\navailability, and sovereignty of data across its lifecycle.\nThese controls govern how data is transmitted, stored,\nreplicated, and protected from unauthorized access, tampering,\nor exposure beyond defined trust perimeters.\n", + "FamilyDescription": "The Data control family ensures the confidentiality, integrity, availability, and sovereignty of data across its lifecycle. These controls govern how data is transmitted, stored, replicated, and protected from unauthorized access, tampering, or exposure beyond defined trust perimeters. ", "Section": "CCC.Core.CN14 Maintain Recent Backups", "SubSection": "", - "SubSectionObjective": "Ensure that all backups used for disaster recovery are recent and\nsubject to a retention policy that limits deletion.", + "SubSectionObjective": "Ensure that all backups used for disaster recovery are recent and subject to a retention policy that limits deletion.", "Applicability": [ "tlp-clear", "tlp-green", "tlp-amber" ], - "Recommendation": "Implement automated backup processes to ensure that backups are\ncreated regularly. Monitor backup schedules and verify that the\nmost recent backup creation date is within the last 30 days.\n", + "Recommendation": "Implement automated backup processes to ensure that backups are created regularly. Monitor backup schedules and verify that the most recent backup creation date is within the last 30 days. ", "SectionThreatMappings": [ { "ReferenceId": "CCC", @@ -7109,18 +5143,18 @@ }, { "Id": "CCC.Core.CN14.AR02", - "Description": "When backups are created for disaster recovery purposes, the\nmost recent backup MUST have a creation date within the past\n14 days.", + "Description": "When backups are created for disaster recovery purposes, the most recent backup MUST have a creation date within the past 14 days.", "Attributes": [ { "FamilyName": "Data", - "FamilyDescription": "The Data control family ensures the confidentiality, integrity,\navailability, and sovereignty of data across its lifecycle.\nThese controls govern how data is transmitted, stored,\nreplicated, and protected from unauthorized access, tampering,\nor exposure beyond defined trust perimeters.\n", + "FamilyDescription": "The Data control family ensures the confidentiality, integrity, availability, and sovereignty of data across its lifecycle. These controls govern how data is transmitted, stored, replicated, and protected from unauthorized access, tampering, or exposure beyond defined trust perimeters. ", "Section": "CCC.Core.CN14 Maintain Recent Backups", "SubSection": "", - "SubSectionObjective": "Ensure that all backups used for disaster recovery are recent and\nsubject to a retention policy that limits deletion.", + "SubSectionObjective": "Ensure that all backups used for disaster recovery are recent and subject to a retention policy that limits deletion.", "Applicability": [ "tlp-red" ], - "Recommendation": "Implement automated backup processes to ensure that backups are\ncreated regularly. Monitor backup schedules and verify that the\nmost recent backup creation date is within the last 14 days.\n", + "Recommendation": "Implement automated backup processes to ensure that backups are created regularly. Monitor backup schedules and verify that the most recent backup creation date is within the last 14 days. ", "SectionThreatMappings": [ { "ReferenceId": "CCC", @@ -7143,14 +5177,14 @@ }, { "Id": "CCC.Core.CN03.AR01", - "Description": "When an entity attempts to modify the service through a user\ninterface, the authentication process MUST require multiple\nidentifying factors for authentication.", + "Description": "When an entity attempts to modify the service through a user interface, the authentication process MUST require multiple identifying factors for authentication.", "Attributes": [ { "FamilyName": "Identity and Access Management", - "FamilyDescription": "The Identity and Access Management control family ensures\nthat only trusted and authenticated entities can access\nresources. These controls establish strong authentication,\nenforce multi-factor verification, and restrict access to\napproved sources to prevent unauthorized use or data exfiltration.\n", + "FamilyDescription": "The Identity and Access Management control family ensures that only trusted and authenticated entities can access resources. These controls establish strong authentication, enforce multi-factor verification, and restrict access to approved sources to prevent unauthorized use or data exfiltration. ", "Section": "CCC.Core.CN03 Implement Multi-factor Authentication (MFA) for Access", "SubSection": "", - "SubSectionObjective": "Ensure that all sensitive activities require two or more identity\nfactors during authentication to prevent unauthorized access.", + "SubSectionObjective": "Ensure that all sensitive activities require two or more identity factors during authentication to prevent unauthorized access.", "Applicability": [ "tlp-clear", "tlp-green", @@ -7211,14 +5245,14 @@ }, { "Id": "CCC.Core.CN03.AR02", - "Description": "When an entity attempts to modify the service through an API\nendpoint, the authentication process MUST require a credential\nsuch as an API key or token AND originate from within the trust\nperimeter.", + "Description": "When an entity attempts to modify the service through an API endpoint, the authentication process MUST require a credential such as an API key or token AND originate from within the trust perimeter.", "Attributes": [ { "FamilyName": "Identity and Access Management", - "FamilyDescription": "The Identity and Access Management control family ensures\nthat only trusted and authenticated entities can access\nresources. These controls establish strong authentication,\nenforce multi-factor verification, and restrict access to\napproved sources to prevent unauthorized use or data exfiltration.\n", + "FamilyDescription": "The Identity and Access Management control family ensures that only trusted and authenticated entities can access resources. These controls establish strong authentication, enforce multi-factor verification, and restrict access to approved sources to prevent unauthorized use or data exfiltration. ", "Section": "CCC.Core.CN03 Implement Multi-factor Authentication (MFA) for Access", "SubSection": "", - "SubSectionObjective": "Ensure that all sensitive activities require two or more identity\nfactors during authentication to prevent unauthorized access.", + "SubSectionObjective": "Ensure that all sensitive activities require two or more identity factors during authentication to prevent unauthorized access.", "Applicability": [ "tlp-clear", "tlp-green", @@ -7279,14 +5313,14 @@ }, { "Id": "CCC.Core.CN03.AR03", - "Description": "When an entity attempts to view information on the service through\na user interface, the authentication process MUST require multiple\nidentifying factors from the user.", + "Description": "When an entity attempts to view information on the service through a user interface, the authentication process MUST require multiple identifying factors from the user.", "Attributes": [ { "FamilyName": "Identity and Access Management", - "FamilyDescription": "The Identity and Access Management control family ensures\nthat only trusted and authenticated entities can access\nresources. These controls establish strong authentication,\nenforce multi-factor verification, and restrict access to\napproved sources to prevent unauthorized use or data exfiltration.\n", + "FamilyDescription": "The Identity and Access Management control family ensures that only trusted and authenticated entities can access resources. These controls establish strong authentication, enforce multi-factor verification, and restrict access to approved sources to prevent unauthorized use or data exfiltration. ", "Section": "CCC.Core.CN03 Implement Multi-factor Authentication (MFA) for Access", "SubSection": "", - "SubSectionObjective": "Ensure that all sensitive activities require two or more identity\nfactors during authentication to prevent unauthorized access.", + "SubSectionObjective": "Ensure that all sensitive activities require two or more identity factors during authentication to prevent unauthorized access.", "Applicability": [ "tlp-amber", "tlp-red" @@ -7346,14 +5380,14 @@ }, { "Id": "CCC.Core.CN03.AR04", - "Description": "When an entity attempts to view information on the service through\nan API endpoint, the authentication process MUST require a\ncredential such as an API key or token AND originate from within\nthe trust perimeter.", + "Description": "When an entity attempts to view information on the service through an API endpoint, the authentication process MUST require a credential such as an API key or token AND originate from within the trust perimeter.", "Attributes": [ { "FamilyName": "Identity and Access Management", - "FamilyDescription": "The Identity and Access Management control family ensures\nthat only trusted and authenticated entities can access\nresources. These controls establish strong authentication,\nenforce multi-factor verification, and restrict access to\napproved sources to prevent unauthorized use or data exfiltration.\n", + "FamilyDescription": "The Identity and Access Management control family ensures that only trusted and authenticated entities can access resources. These controls establish strong authentication, enforce multi-factor verification, and restrict access to approved sources to prevent unauthorized use or data exfiltration. ", "Section": "CCC.Core.CN03 Implement Multi-factor Authentication (MFA) for Access", "SubSection": "", - "SubSectionObjective": "Ensure that all sensitive activities require two or more identity\nfactors during authentication to prevent unauthorized access.", + "SubSectionObjective": "Ensure that all sensitive activities require two or more identity factors during authentication to prevent unauthorized access.", "Applicability": [ "tlp-amber", "tlp-red" @@ -7414,14 +5448,14 @@ }, { "Id": "CCC.Core.CN05.AR01", - "Description": "When an attempt is made to modify data on the service or a child\nresource, the service MUST block requests from unauthorized\nentities.", + "Description": "When an attempt is made to modify data on the service or a child resource, the service MUST block requests from unauthorized entities.", "Attributes": [ { "FamilyName": "Identity and Access Management", - "FamilyDescription": "The Identity and Access Management control family ensures\nthat only trusted and authenticated entities can access\nresources. These controls establish strong authentication,\nenforce multi-factor verification, and restrict access to\napproved sources to prevent unauthorized use or data exfiltration.\n", + "FamilyDescription": "The Identity and Access Management control family ensures that only trusted and authenticated entities can access resources. These controls establish strong authentication, enforce multi-factor verification, and restrict access to approved sources to prevent unauthorized use or data exfiltration. ", "Section": "CCC.Core.CN05 Prevent Access from Untrusted Entities", "SubSection": "", - "SubSectionObjective": "Ensure that secure access controls enforce the principle of least\nprivilege to restrict access to authorized entities from explicitly\ntrusted sources only.", + "SubSectionObjective": "Ensure that secure access controls enforce the principle of least privilege to restrict access to authorized entities from explicitly trusted sources only.", "Applicability": [ "tlp-clear", "tlp-green", @@ -7496,14 +5530,14 @@ }, { "Id": "CCC.Core.CN05.AR02", - "Description": "When administrative access or configuration change is attempted on\nthe service or a child resource, the service MUST refuse requests\nfrom unauthorized entities.", + "Description": "When administrative access or configuration change is attempted on the service or a child resource, the service MUST refuse requests from unauthorized entities.", "Attributes": [ { "FamilyName": "Identity and Access Management", - "FamilyDescription": "The Identity and Access Management control family ensures\nthat only trusted and authenticated entities can access\nresources. These controls establish strong authentication,\nenforce multi-factor verification, and restrict access to\napproved sources to prevent unauthorized use or data exfiltration.\n", + "FamilyDescription": "The Identity and Access Management control family ensures that only trusted and authenticated entities can access resources. These controls establish strong authentication, enforce multi-factor verification, and restrict access to approved sources to prevent unauthorized use or data exfiltration. ", "Section": "CCC.Core.CN05 Prevent Access from Untrusted Entities", "SubSection": "", - "SubSectionObjective": "Ensure that secure access controls enforce the principle of least\nprivilege to restrict access to authorized entities from explicitly\ntrusted sources only.", + "SubSectionObjective": "Ensure that secure access controls enforce the principle of least privilege to restrict access to authorized entities from explicitly trusted sources only.", "Applicability": [ "tlp-clear", "tlp-green", @@ -7581,14 +5615,14 @@ }, { "Id": "CCC.Core.CN05.AR03", - "Description": "When administrative access or configuration change is attempted on\nthe service or a child resource in a multi-tenant environment, the\nservice MUST refuse requests across tenant boundaries unless the\norigin is explicitly included in a pre-approved allowlist.", + "Description": "When administrative access or configuration change is attempted on the service or a child resource in a multi-tenant environment, the service MUST refuse requests across tenant boundaries unless the origin is explicitly included in a pre-approved allowlist.", "Attributes": [ { "FamilyName": "Identity and Access Management", - "FamilyDescription": "The Identity and Access Management control family ensures\nthat only trusted and authenticated entities can access\nresources. These controls establish strong authentication,\nenforce multi-factor verification, and restrict access to\napproved sources to prevent unauthorized use or data exfiltration.\n", + "FamilyDescription": "The Identity and Access Management control family ensures that only trusted and authenticated entities can access resources. These controls establish strong authentication, enforce multi-factor verification, and restrict access to approved sources to prevent unauthorized use or data exfiltration. ", "Section": "CCC.Core.CN05 Prevent Access from Untrusted Entities", "SubSection": "", - "SubSectionObjective": "Ensure that secure access controls enforce the principle of least\nprivilege to restrict access to authorized entities from explicitly\ntrusted sources only.", + "SubSectionObjective": "Ensure that secure access controls enforce the principle of least privilege to restrict access to authorized entities from explicitly trusted sources only.", "Applicability": [ "tlp-clear", "tlp-green", @@ -7648,14 +5682,14 @@ }, { "Id": "CCC.Core.CN05.AR04", - "Description": "When data is requested from outside the trust perimeter, the\nservice MUST refuse requests from unauthorized entities.", + "Description": "When data is requested from outside the trust perimeter, the service MUST refuse requests from unauthorized entities.", "Attributes": [ { "FamilyName": "Identity and Access Management", - "FamilyDescription": "The Identity and Access Management control family ensures\nthat only trusted and authenticated entities can access\nresources. These controls establish strong authentication,\nenforce multi-factor verification, and restrict access to\napproved sources to prevent unauthorized use or data exfiltration.\n", + "FamilyDescription": "The Identity and Access Management control family ensures that only trusted and authenticated entities can access resources. These controls establish strong authentication, enforce multi-factor verification, and restrict access to approved sources to prevent unauthorized use or data exfiltration. ", "Section": "", "SubSection": "CCC.Core.CN05 Prevent Access from Untrusted Entities", - "SubSectionObjective": "Ensure that secure access controls enforce the principle of least\nprivilege to restrict access to authorized entities from explicitly\ntrusted sources only.", + "SubSectionObjective": "Ensure that secure access controls enforce the principle of least privilege to restrict access to authorized entities from explicitly trusted sources only.", "Applicability": [ "tlp-amber", "tlp-red" @@ -7722,14 +5756,14 @@ }, { "Id": "CCC.Core.CN05.AR05", - "Description": "When any request is made from outside the trust perimeter,\nthe service MUST NOT provide any response that may indicate the\nservice exists.", + "Description": "When any request is made from outside the trust perimeter, the service MUST NOT provide any response that may indicate the service exists.", "Attributes": [ { "FamilyName": "Identity and Access Management", - "FamilyDescription": "The Identity and Access Management control family ensures\nthat only trusted and authenticated entities can access\nresources. These controls establish strong authentication,\nenforce multi-factor verification, and restrict access to\napproved sources to prevent unauthorized use or data exfiltration.\n", + "FamilyDescription": "The Identity and Access Management control family ensures that only trusted and authenticated entities can access resources. These controls establish strong authentication, enforce multi-factor verification, and restrict access to approved sources to prevent unauthorized use or data exfiltration. ", "Section": "CCC.Core.CN05 Prevent Access from Untrusted Entities", "SubSection": "", - "SubSectionObjective": "Ensure that secure access controls enforce the principle of least\nprivilege to restrict access to authorized entities from explicitly\ntrusted sources only.", + "SubSectionObjective": "Ensure that secure access controls enforce the principle of least privilege to restrict access to authorized entities from explicitly trusted sources only.", "Applicability": [ "tlp-red" ], @@ -7797,14 +5831,14 @@ }, { "Id": "CCC.Core.CN05.AR06", - "Description": "When any request is made to the service or a child resource, the\nservice MUST refuse requests from unauthorized entities.", + "Description": "When any request is made to the service or a child resource, the service MUST refuse requests from unauthorized entities.", "Attributes": [ { "FamilyName": "Identity and Access Management", - "FamilyDescription": "The Identity and Access Management control family ensures\nthat only trusted and authenticated entities can access\nresources. These controls establish strong authentication,\nenforce multi-factor verification, and restrict access to\napproved sources to prevent unauthorized use or data exfiltration.\n", + "FamilyDescription": "The Identity and Access Management control family ensures that only trusted and authenticated entities can access resources. These controls establish strong authentication, enforce multi-factor verification, and restrict access to approved sources to prevent unauthorized use or data exfiltration. ", "Section": "CCC.Core.CN05 Prevent Access from Untrusted Entities", "SubSection": "", - "SubSectionObjective": "Ensure that secure access controls enforce the principle of least\nprivilege to restrict access to authorized entities from explicitly\ntrusted sources only.", + "SubSectionObjective": "Ensure that secure access controls enforce the principle of least privilege to restrict access to authorized entities from explicitly trusted sources only.", "Applicability": [ "tlp-green", "tlp-amber", @@ -7870,14 +5904,14 @@ }, { "Id": "CCC.Core.CN04.AR01", - "Description": "When administrative access or configuration change is attempted on\nthe service or a child resource, the service MUST log the client\nidentity, time, and result of the attempt.", + "Description": "When administrative access or configuration change is attempted on the service or a child resource, the service MUST log the client identity, time, and result of the attempt.", "Attributes": [ { "FamilyName": "Logging & Monitoring", - "FamilyDescription": "The Logging & Monitoring control family ensures that access,\nchanges, and security-relevant events are captured, monitored,\nand alerted on in order to provide visibility, support\nincident response, and meet compliance requirements.\n", + "FamilyDescription": "The Logging & Monitoring control family ensures that access, changes, and security-relevant events are captured, monitored, and alerted on in order to provide visibility, support incident response, and meet compliance requirements. ", "Section": "CCC.Core.CN04 Log All Access and Changes", "SubSection": "", - "SubSectionObjective": "Ensure that all access attempts are logged to maintain a detailed\naudit trail for security and compliance purposes.", + "SubSectionObjective": "Ensure that all access attempts are logged to maintain a detailed audit trail for security and compliance purposes.", "Applicability": [ "tlp-clear", "tlp-green", @@ -7943,14 +5977,14 @@ }, { "Id": "CCC.Core.CN04.AR02", - "Description": "When any attempt is made to modify data on the service or a child\nresource, the service MUST log the client identity, time, and\nresult of the attempt.", + "Description": "When any attempt is made to modify data on the service or a child resource, the service MUST log the client identity, time, and result of the attempt.", "Attributes": [ { "FamilyName": "Logging & Monitoring", - "FamilyDescription": "The Logging & Monitoring control family ensures that access,\nchanges, and security-relevant events are captured, monitored,\nand alerted on in order to provide visibility, support\nincident response, and meet compliance requirements.\n", + "FamilyDescription": "The Logging & Monitoring control family ensures that access, changes, and security-relevant events are captured, monitored, and alerted on in order to provide visibility, support incident response, and meet compliance requirements. ", "Section": "CCC.Core.CN04 Log All Access and Changes", "SubSection": "", - "SubSectionObjective": "Ensure that all access attempts are logged to maintain a detailed\naudit trail for security and compliance purposes.", + "SubSectionObjective": "Ensure that all access attempts are logged to maintain a detailed audit trail for security and compliance purposes.", "Applicability": [ "tlp-amber", "tlp-red" @@ -8004,14 +6038,14 @@ }, { "Id": "CCC.Core.CN04.AR03", - "Description": "When any attempt is made to read data on the service or a child\nresource, the service MUST log the client identity, time, and\nresult of the attempt.", + "Description": "When any attempt is made to read data on the service or a child resource, the service MUST log the client identity, time, and result of the attempt.", "Attributes": [ { "FamilyName": "Logging & Monitoring", - "FamilyDescription": "The Logging & Monitoring control family ensures that access,\nchanges, and security-relevant events are captured, monitored,\nand alerted on in order to provide visibility, support\nincident response, and meet compliance requirements.\n", + "FamilyDescription": "The Logging & Monitoring control family ensures that access, changes, and security-relevant events are captured, monitored, and alerted on in order to provide visibility, support incident response, and meet compliance requirements. ", "Section": "CCC.Core.CN04 Log All Access and Changes", "SubSection": "", - "SubSectionObjective": "Ensure that all access attempts are logged to maintain a detailed\naudit trail for security and compliance purposes.", + "SubSectionObjective": "Ensure that all access attempts are logged to maintain a detailed audit trail for security and compliance purposes.", "Applicability": [ "tlp-red" ], @@ -8068,19 +6102,19 @@ }, { "Id": "CCC.Core.CN07.AR01", - "Description": "When enumeration activities are detected, the service MUST publish\nan event to a monitored channel which includes the client\nidentity, time, and nature of the activity.", + "Description": "When enumeration activities are detected, the service MUST publish an event to a monitored channel which includes the client identity, time, and nature of the activity.", "Attributes": [ { "FamilyName": "Logging & Monitoring", - "FamilyDescription": "The Logging & Monitoring control family ensures that access,\nchanges, and security-relevant events are captured, monitored,\nand alerted on in order to provide visibility, support\nincident response, and meet compliance requirements.\n", + "FamilyDescription": "The Logging & Monitoring control family ensures that access, changes, and security-relevant events are captured, monitored, and alerted on in order to provide visibility, support incident response, and meet compliance requirements. ", "Section": "CCC.Core.CN07 Alert on Unusual Enumeration Activity", "SubSection": "", - "SubSectionObjective": "Ensure that logs and associated alerts are generated when\nunusual enumeration activity is detected that may indicate\nreconnaissance activities.", + "SubSectionObjective": "Ensure that logs and associated alerts are generated when unusual enumeration activity is detected that may indicate reconnaissance activities.", "Applicability": [ "tlp-amber", "tlp-red" ], - "Recommendation": "Implement event publication mechanisms and alerts for patterns\nindicative of enumeration activities, such as repeated access\nattempts, requests, or liveness probes. Configure alerts to notify\nsecurity teams of any activities that merit further investigation.\n", + "Recommendation": "Implement event publication mechanisms and alerts for patterns indicative of enumeration activities, such as repeated access attempts, requests, or liveness probes. Configure alerts to notify security teams of any activities that merit further investigation. ", "SectionThreatMappings": [ { "ReferenceId": "CCC", @@ -8118,21 +6152,21 @@ }, { "Id": "CCC.Core.CN07.AR02", - "Description": "When enumeration activities are detected, the service MUST log the\nclient identity, time, and nature of the activity.", + "Description": "When enumeration activities are detected, the service MUST log the client identity, time, and nature of the activity.", "Attributes": [ { "FamilyName": "Logging & Monitoring", - "FamilyDescription": "The Logging & Monitoring control family ensures that access,\nchanges, and security-relevant events are captured, monitored,\nand alerted on in order to provide visibility, support\nincident response, and meet compliance requirements.\n", + "FamilyDescription": "The Logging & Monitoring control family ensures that access, changes, and security-relevant events are captured, monitored, and alerted on in order to provide visibility, support incident response, and meet compliance requirements. ", "Section": "CCC.Core.CN07 Alert on Unusual Enumeration Activity", "SubSection": "", - "SubSectionObjective": "Ensure that logs and associated alerts are generated when\nunusual enumeration activity is detected that may indicate\nreconnaissance activities.", + "SubSectionObjective": "Ensure that logs and associated alerts are generated when unusual enumeration activity is detected that may indicate reconnaissance activities.", "Applicability": [ "tlp-clear", "tlp-green", "tlp-amber", "tlp-red" ], - "Recommendation": "Implement logging mechanisms to capture details of enumeration\nactivities, including client identity, timestamps, and activity\nnature. Retain logs according to organizational policies, and\noccasionally review them for patterns that may indicate\nreconnaissance activities.\n", + "Recommendation": "Implement logging mechanisms to capture details of enumeration activities, including client identity, timestamps, and activity nature. Retain logs according to organizational policies, and occasionally review them for patterns that may indicate reconnaissance activities. ", "SectionThreatMappings": [ { "ReferenceId": "CCC", diff --git a/prowler/compliance/azure/ccc_azure.json b/prowler/compliance/azure/ccc_azure.json index efc2188406..004137ad53 100644 --- a/prowler/compliance/azure/ccc_azure.json +++ b/prowler/compliance/azure/ccc_azure.json @@ -6,19 +6,19 @@ "Description": "Common Cloud Controls Catalog (CCC) for Azure", "Requirements": [ { - "Id": "CCC.AuditLog.C01.TR01", + "Id": "CCC.AuditLog.CN01.AR01", "Description": "When the signature validation process is performed, then it MUST detect any modification of data.", "Attributes": [ { "FamilyName": "Integrity", "FamilyDescription": "Controls designed to protected the integrity of Audit Log data.", - "Section": "CCC.AuditLog.C01 Implement Digital Signatures With Hash Chaining", + "Section": "CCC.AuditLog.CN01 Implement Digital Signatures With Hash Chaining", "SubSection": "", - "SubSectionObjective": "Digital signatures allows for external verification of log data tampering and\nhash chaining allows for deleted log files to be detected.", + "SubSectionObjective": "Digital signatures allows for external verification of log data tampering and hash chaining allows for deleted log files to be detected.", "Applicability": [ "tlp-red" ], - "Recommendation": "Ensure hash of data is included in digital signature.\n", + "Recommendation": "Ensure hash of data is included in digital signature. ", "SectionThreatMappings": [ { "ReferenceId": "CCC", @@ -47,19 +47,19 @@ "Checks": [] }, { - "Id": "CCC.AuditLog.C01.TR02", + "Id": "CCC.AuditLog.CN01.AR02", "Description": "When the signature validation process is performed, then it MUST detect any missing (deleted) log file.", "Attributes": [ { "FamilyName": "Integrity", "FamilyDescription": "Controls designed to protected the integrity of Audit Log data.", - "Section": "CCC.AuditLog.C01 Implement Digital Signatures With Hash Chaining", + "Section": "CCC.AuditLog.CN01 Implement Digital Signatures With Hash Chaining", "SubSection": "", - "SubSectionObjective": "Digital signatures allows for external verification of log data tampering and\nhash chaining allows for deleted log files to be detected.", + "SubSectionObjective": "Digital signatures allows for external verification of log data tampering and hash chaining allows for deleted log files to be detected.", "Applicability": [ "tlp-red" ], - "Recommendation": "Ensure verification process includes a chained hash function.\n", + "Recommendation": "Ensure verification process includes a chained hash function. ", "SectionThreatMappings": [ { "ReferenceId": "CCC", @@ -88,15 +88,15 @@ "Checks": [] }, { - "Id": "CCC.AuditLog.C02.TR01", - "Description": "When a manual action is performed to generate each audit log type,\nthen the corresponding audit log type MUST be generated and recorded.", + "Id": "CCC.AuditLog.CN02.AR01", + "Description": "When a manual action is performed to generate each audit log type, then the corresponding audit log type MUST be generated and recorded.", "Attributes": [ { "FamilyName": "Integrity", "FamilyDescription": "Controls designed to protected the integrity of Audit Log data.", - "Section": "CCC.AuditLog.C02 Enable And Validate All Audit Log Types", + "Section": "CCC.AuditLog.CN02 Enable And Validate All Audit Log Types", "SubSection": "", - "SubSectionObjective": "Review audit log configuration and ensure that all audit log types\nare being generated and replicated to configured sinks", + "SubSectionObjective": "Review audit log configuration and ensure that all audit log types are being generated and replicated to configured sinks", "Applicability": [ "tlp-red", "tlp-amber" @@ -136,20 +136,20 @@ ] }, { - "Id": "CCC.AuditLog.C03.TR01", + "Id": "CCC.AuditLog.CN03.AR01", "Description": "When an attempt is made to disable a log source, then an alert MUST be generated.", "Attributes": [ { "FamilyName": "Integrity", "FamilyDescription": "Controls designed to protected the integrity of Audit Log data.", - "Section": "CCC.AuditLog.C03 Alert On Audit Log Changes And Access", + "Section": "CCC.AuditLog.CN03 Alert On Audit Log Changes And Access", "SubSection": "", - "SubSectionObjective": "Ensure that specific alerts have been configured to detect changes in\naudit log configuration such as disabling exporting of logs.\nAlerts MUST also be created to detect changes in retention/object lock policies\nfor exported data log sources/buckets.", + "SubSectionObjective": "Ensure that specific alerts have been configured to detect changes in audit log configuration such as disabling exporting of logs. Alerts MUST also be created to detect changes in retention/object lock policies for exported data log sources/buckets.", "Applicability": [ "tlp-red", "tlp-amber" ], - "Recommendation": "Ensure alerting is correctly configured\n", + "Recommendation": "Ensure alerting is correctly configured ", "SectionThreatMappings": [ { "ReferenceId": "CCC", @@ -183,20 +183,20 @@ ] }, { - "Id": "CCC.AuditLog.C03.TR02", - "Description": "When an attempt is made to alter the retention or object lock status\nof an external data log source or bucket, then an alert MUST be generated.", + "Id": "CCC.AuditLog.CN03.AR02", + "Description": "When an attempt is made to alter the retention or object lock status of an external data log source or bucket, then an alert MUST be generated.", "Attributes": [ { "FamilyName": "Integrity", "FamilyDescription": "Controls designed to protected the integrity of Audit Log data.", - "Section": "CCC.AuditLog.C03 Alert On Audit Log Changes And Access", + "Section": "CCC.AuditLog.CN03 Alert On Audit Log Changes And Access", "SubSection": "", - "SubSectionObjective": "Ensure that specific alerts have been configured to detect changes in\naudit log configuration such as disabling exporting of logs.\nAlerts MUST also be created to detect changes in retention/object lock policies\nfor exported data log sources/buckets.", + "SubSectionObjective": "Ensure that specific alerts have been configured to detect changes in audit log configuration such as disabling exporting of logs. Alerts MUST also be created to detect changes in retention/object lock policies for exported data log sources/buckets.", "Applicability": [ "tlp-red", "tlp-amber" ], - "Recommendation": "Ensure alerting is correctly configured\n", + "Recommendation": "Ensure alerting is correctly configured ", "SectionThreatMappings": [ { "ReferenceId": "CCC", @@ -240,20 +240,20 @@ ] }, { - "Id": "CCC.AuditLog.C04.TR01", - "Description": "When audit log buckets are created then verify that server access\nlogging MUST be enabled for the audit log bucket,\nwith logs delivered to a separate, secure logging bucket.", + "Id": "CCC.AuditLog.CN04.AR01", + "Description": "When audit log buckets are created then verify that server access logging MUST be enabled for the audit log bucket, with logs delivered to a separate, secure logging bucket.", "Attributes": [ { "FamilyName": "Integrity", "FamilyDescription": "Controls designed to protected the integrity of Audit Log data.", - "Section": "CCC.AuditLog.C04 Ensure Access Logging Is Enabled on the Audit Log Bucket", + "Section": "CCC.AuditLog.CN04 Ensure Access Logging Is Enabled on the Audit Log Bucket", "SubSection": "", - "SubSectionObjective": "Ensure that access logging is enabled for the audit log storage bucket to\ncapture all requests made to the bucket, providing an audit trail of data access.", + "SubSectionObjective": "Ensure that access logging is enabled for the audit log storage bucket to capture all requests made to the bucket, providing an audit trail of data access.", "Applicability": [ "tlp-red", "tlp-amber" ], - "Recommendation": "Configure the audit log bucket to enable server access logging.\nEnsure the target logging bucket is configured for appropriate security,\nincluding restricted access and immutability.\n", + "Recommendation": "Configure the audit log bucket to enable server access logging. Ensure the target logging bucket is configured for appropriate security, including restricted access and immutability. ", "SectionThreatMappings": [ { "ReferenceId": "CCC", @@ -289,20 +289,20 @@ ] }, { - "Id": "CCC.AuditLog.C05.TR01", + "Id": "CCC.AuditLog.CN05.AR01", "Description": "When audit logs are exported, then audit logs MUST be present in the configured data location.", "Attributes": [ { "FamilyName": "Availability", "FamilyDescription": "Controls designed to protected the availability of Audit Log data.", - "Section": "CCC.AuditLog.C05 Export Audit Logs To Bucket", + "Section": "CCC.AuditLog.CN05 Export Audit Logs To Bucket", "SubSection": "", - "SubSectionObjective": "Configure audit logs to be sent to a external bucket where they can be globally replicated\nand can be subject to greater access control and data retention polices.", + "SubSectionObjective": "Configure audit logs to be sent to a external bucket where they can be globally replicated and can be subject to greater access control and data retention polices.", "Applicability": [ "tlp-red", "tlp-amber" ], - "Recommendation": "Configure audit log exporting.\n", + "Recommendation": "Configure audit log exporting. ", "SectionThreatMappings": [ { "ReferenceId": "CCC", @@ -337,21 +337,21 @@ ] }, { - "Id": "CCC.AuditLog.C06.TR01", - "Description": "When the retention policy is applied, then data MUST\nbe automatically deleted after the configured number of days.", + "Id": "CCC.AuditLog.CN06.AR01", + "Description": "When the retention policy is applied, then data MUST be automatically deleted after the configured number of days.", "Attributes": [ { "FamilyName": "Availability", "FamilyDescription": "Controls designed to protected the availability of Audit Log data.", - "Section": "CCC.AuditLog.C06 Enforce Retention Policy on Audit Log Bucket", + "Section": "CCC.AuditLog.CN06 Enforce Retention Policy on Audit Log Bucket", "SubSection": "", - "SubSectionObjective": "Configure a custom retention policy on the designated audit log bucket to ensure that logs are\nretained for the correct number of days as defined by your organization's policy.", + "SubSectionObjective": "Configure a custom retention policy on the designated audit log bucket to ensure that logs are retained for the correct number of days as defined by your organization's policy.", "Applicability": [ "tlp-red", "tlp-amber", "tlp-green" ], - "Recommendation": "Configure the audit log bucket's lifecycle rules or object retention settings to enforce\nthe required data retention period.\n", + "Recommendation": "Configure the audit log bucket's lifecycle rules or object retention settings to enforce the required data retention period. ", "SectionThreatMappings": [ { "ReferenceId": "CCC", @@ -384,21 +384,21 @@ ] }, { - "Id": "CCC.AuditLog.C07.TR01", - "Description": "When a standard file deletion is attempted on an object within\nthe audit log bucket, then it MUST be prevented unless MFA is provided.", + "Id": "CCC.AuditLog.CN07.AR01", + "Description": "When a standard file deletion is attempted on an object within the audit log bucket, then it MUST be prevented unless MFA is provided.", "Attributes": [ { "FamilyName": "Availability", "FamilyDescription": "Controls designed to protected the availability of Audit Log data.", - "Section": "CCC.AuditLog.C07 Enforce MFA Delete on Audit Log Bucket", + "Section": "CCC.AuditLog.CN07 Enforce MFA Delete on Audit Log Bucket", "SubSection": "", - "SubSectionObjective": "Enable Multi-Factor Authentication (MFA) delete on the audit log bucket to\nprovide greater protection against accidental or malicious deletion of audit data.", + "SubSectionObjective": "Enable Multi-Factor Authentication (MFA) delete on the audit log bucket to provide greater protection against accidental or malicious deletion of audit data.", "Applicability": [ "tlp-red", "tlp-amber", "tlp-green" ], - "Recommendation": "Enable MFA Delete (or equivalent multi-factor authentication for delete operations)\non the audit log bucket.\n", + "Recommendation": "Enable MFA Delete (or equivalent multi-factor authentication for delete operations) on the audit log bucket. ", "SectionThreatMappings": [ { "ReferenceId": "CCC", @@ -428,20 +428,20 @@ "Checks": [] }, { - "Id": "CCC.AuditLog.C08.TR01", - "Description": "When an attempt is made to delete data before the object\nlock period expires, then the deletion MUST be denied.", + "Id": "CCC.AuditLog.CN08.AR01", + "Description": "When an attempt is made to delete data before the object lock period expires, then the deletion MUST be denied.", "Attributes": [ { "FamilyName": "Availability", "FamilyDescription": "Controls designed to protected the availability of Audit Log data.", - "Section": "CCC.AuditLog.C08 Enable Object Lock On Audit Log Bucket", + "Section": "CCC.AuditLog.CN08 Enable Object Lock On Audit Log Bucket", "SubSection": "", - "SubSectionObjective": "Ensure that object log is enabled globally on all objects with the bucket.\nThe lock time MUST be configured to meet your organization, legal and compliance goals.\nDeletion attempts before the lock period MUST be denied.", + "SubSectionObjective": "Ensure that object log is enabled globally on all objects with the bucket. The lock time MUST be configured to meet your organization, legal and compliance goals. Deletion attempts before the lock period MUST be denied.", "Applicability": [ "tlp-red", "tlp-amber" ], - "Recommendation": "Configure object lock policy.\n", + "Recommendation": "Configure object lock policy. ", "SectionThreatMappings": [ { "ReferenceId": "CCC", @@ -475,20 +475,20 @@ ] }, { - "Id": "CCC.AuditLog.C09.TR01", + "Id": "CCC.AuditLog.CN09.AR01", "Description": "When restricted fields are accessed by unauthorized users, then those fields MUST remain masked.", "Attributes": [ { "FamilyName": "Confidentiality", "FamilyDescription": "Controls designed to protected the confidentiality of Audit Log data.", - "Section": "CCC.AuditLog.C09 Restrict Field And Log Type Access", + "Section": "CCC.AuditLog.CN09 Restrict Field And Log Type Access", "SubSection": "", - "SubSectionObjective": "Configure access to audit logs to follow the principle of least privilege in particular where technically\npossible limit the log fields users have access to to prevent accidental exposure to sensitive\ninformation such as PII.", + "SubSectionObjective": "Configure access to audit logs to follow the principle of least privilege in particular where technically possible limit the log fields users have access to to prevent accidental exposure to sensitive information such as PII.", "Applicability": [ "tlp-red", "tlp-amber" ], - "Recommendation": "Review field level access controls on audit data.\n", + "Recommendation": "Review field level access controls on audit data. ", "SectionThreatMappings": [ { "ReferenceId": "CCC", @@ -525,21 +525,21 @@ ] }, { - "Id": "CCC.AuditLog.C10.TR01", - "Description": "When audit log storage bucket's are created then, bucket's access control settings MUST explicitly deny\npublic read and write access.", + "Id": "CCC.AuditLog.CN10.AR01", + "Description": "When audit log storage bucket's are created then, bucket's access control settings MUST explicitly deny public read and write access.", "Attributes": [ { "FamilyName": "Confidentiality", "FamilyDescription": "Controls designed to protected the confidentiality of Audit Log data.", - "Section": "CCC.AuditLog.C10 Ensure Audit Bucket is Not Publicly Accessible", + "Section": "CCC.AuditLog.CN10 Ensure Audit Bucket is Not Publicly Accessible", "SubSection": "", - "SubSectionObjective": "Ensure that audit log storage buckets are not publicly accessible to prevent\nunauthorized exposure of sensitive log data.", + "SubSectionObjective": "Ensure that audit log storage buckets are not publicly accessible to prevent unauthorized exposure of sensitive log data.", "Applicability": [ "tlp-red", "tlp-amber", "tlp-green" ], - "Recommendation": "Configure bucket policies and access control lists (ACLs) to restrict public access.\nRegularly review bucket permissions to ensure no public access has been inadvertently granted.\n", + "Recommendation": "Configure bucket policies and access control lists (ACLs) to restrict public access. Regularly review bucket permissions to ensure no public access has been inadvertently granted. ", "SectionThreatMappings": [ { "ReferenceId": "CCC", @@ -573,21 +573,21 @@ ] }, { - "Id": "CCC.AuditLog.C10.TR02", - "Description": "When the URL of a audit log storage bucket's object is accessed publicly then,\nit should be denied by bucket policy.", + "Id": "CCC.AuditLog.CN10.AR02", + "Description": "When the URL of a audit log storage bucket's object is accessed publicly then, it should be denied by bucket policy.", "Attributes": [ { "FamilyName": "Confidentiality", "FamilyDescription": "Controls designed to protected the confidentiality of Audit Log data.", - "Section": "CCC.AuditLog.C10 Ensure Audit Bucket is Not Publicly Accessible", + "Section": "CCC.AuditLog.CN10 Ensure Audit Bucket is Not Publicly Accessible", "SubSection": "", - "SubSectionObjective": "Ensure that audit log storage buckets are not publicly accessible to prevent\nunauthorized exposure of sensitive log data.", + "SubSectionObjective": "Ensure that audit log storage buckets are not publicly accessible to prevent unauthorized exposure of sensitive log data.", "Applicability": [ "tlp-red", "tlp-amber", "tlp-green" ], - "Recommendation": "Configure bucket policies and access control lists (ACLs) to restrict public access.\nRegularly review bucket permissions to ensure no public access has been inadvertently granted.\n", + "Recommendation": "Configure bucket policies and access control lists (ACLs) to restrict public access. Regularly review bucket permissions to ensure no public access has been inadvertently granted. ", "SectionThreatMappings": [ { "ReferenceId": "CCC", @@ -622,15 +622,15 @@ ] }, { - "Id": "CCC.Build.C01.TR01", + "Id": "CCC.Build.CN01.AR01", "Description": "Attempt to initiate a build using an unauthorized build agent and verify that the build is rejected.", "Attributes": [ { "FamilyName": "Access Control", "FamilyDescription": "TODO: Describe this control family", - "Section": "CCC.Build.C01 Restrict Allowed Build Agents", + "Section": "CCC.Build.CN01 Restrict Allowed Build Agents", "SubSection": "", - "SubSectionObjective": "Ensure that builds are executed only on authorized build agents to maintain\ncontrol over the build environment and prevent unauthorized code execution.", + "SubSectionObjective": "Ensure that builds are executed only on authorized build agents to maintain control over the build environment and prevent unauthorized code execution.", "Applicability": [ "tlp-red", "tlp-amber" @@ -664,15 +664,15 @@ "Checks": [] }, { - "Id": "CCC.Build.C02.TR01", - "Description": "Attempt to trigger a build from an unauthorized external service or\nrepository and verify that the build does not start.", + "Id": "CCC.Build.CN02.AR01", + "Description": "Attempt to trigger a build from an unauthorized external service or repository and verify that the build does not start.", "Attributes": [ { "FamilyName": "Access Control", "FamilyDescription": "TODO: Describe this control family", - "Section": "CCC.Build.C02 Restrict Allowed External Services for Build Triggers", + "Section": "CCC.Build.CN02 Restrict Allowed External Services for Build Triggers", "SubSection": "", - "SubSectionObjective": "Ensure that builds can only be triggered by authorized external services or\nrepositories to prevent unauthorized code execution or tampering.", + "SubSectionObjective": "Ensure that builds can only be triggered by authorized external services or repositories to prevent unauthorized code execution or tampering.", "Applicability": [ "tlp-red", "tlp-amber" @@ -706,15 +706,15 @@ "Checks": [] }, { - "Id": "CCC.Build.C03.TR01", + "Id": "CCC.Build.CN03.AR01", "Description": "Attempt to access the build environment from an external network and verify that access is denied.", "Attributes": [ { "FamilyName": "Network Security", "FamilyDescription": "TODO: Describe this control family", - "Section": "CCC.Build.C03 Deny External Network Access for Build Environments", + "Section": "CCC.Build.CN03 Deny External Network Access for Build Environments", "SubSection": "", - "SubSectionObjective": "Ensure that build environments do not have external network access to\nprevent unauthorized external access and data exfiltration.", + "SubSectionObjective": "Ensure that build environments do not have external network access to prevent unauthorized external access and data exfiltration.", "Applicability": [ "tlp-red", "tlp-amber" @@ -758,15 +758,15 @@ ] }, { - "Id": "CCC.CntrReg.C01.TR01", - "Description": "Attempt to push an artifact with known vulnerabilities to the registry\nand observe if it is flagged or rejected by the vulnerability scanning process.", + "Id": "CCC.CntrReg.CN01.AR01", + "Description": "Attempt to push an artifact with known vulnerabilities to the registry and observe if it is flagged or rejected by the vulnerability scanning process.", "Attributes": [ { "FamilyName": "Risk Management", "FamilyDescription": "TODO: Describe this control family", - "Section": "CCC.CntrReg.C01 Implement Vulnerability Scanning for Artifacts", + "Section": "CCC.CntrReg.CN01 Implement Vulnerability Scanning for Artifacts", "SubSection": "", - "SubSectionObjective": "Ensure that container images and artifacts stored in the container registry are scanned for\nvulnerabilities to identify and remediate security issues before deployment.", + "SubSectionObjective": "Ensure that container images and artifacts stored in the container registry are scanned for vulnerabilities to identify and remediate security issues before deployment.", "Applicability": [ "tlp-red", "tlp-amber" @@ -803,60 +803,15 @@ ] }, { - "Id": "CCC.CntrReg.C02.TR01", - "Description": "Confirm that artifacts older than the specified retention period are automatically\ndeleted from the registry.", - "Attributes": [ - { - "FamilyName": "Data Management", - "FamilyDescription": "TODO: Describe this control family", - "Section": "CCC.CntrReg.C02 Implement Cleanup Policies for Artifacts", - "SubSection": "", - "SubSectionObjective": "Ensure that unused or outdated artifacts are cleaned up according to defined policies to\nmanage storage effectively and reduce security risks associated with outdated versions.", - "Applicability": [ - "tlp-red", - "tlp-amber" - ], - "Recommendation": "", - "SectionThreatMappings": [ - { - "ReferenceId": "CCC", - "Identifiers": [ - "CCC.TH14" - ] - } - ], - "SectionGuidelineMappings": [ - { - "ReferenceId": "NIST-CSF", - "Identifiers": [ - "PR.IP-6" - ] - }, - { - "ReferenceId": "NIST_800_53", - "Identifiers": [ - "SI-12" - ] - } - ] - } - ], - "Checks": [ - "containerregistry_not_publicly_accessible", - "containerregistry_uses_private_link", - "containerregistry_admin_user_disabled" - ] - }, - { - "Id": "CCC.DataWar.C01.TR01", - "Description": "Attempt to access underlying database tables directly without\nusing managed views and verify that access is denied.", + "Id": "CCC.DataWar.CN01.AR01", + "Description": "Attempt to access underlying database tables directly without using managed views and verify that access is denied.", "Attributes": [ { "FamilyName": "Data", "FamilyDescription": "TODO: Describe this control family", - "Section": "CCC.DataWar.C01 Enforce Use of Managed Views for Data Access", + "Section": "CCC.DataWar.CN01 Enforce Use of Managed Views for Data Access", "SubSection": "", - "SubSectionObjective": "Ensure that data access is provided through managed views, restricting users\nfrom accessing underlying tables directly and enforcing consistent security policies.", + "SubSectionObjective": "Ensure that data access is provided through managed views, restricting users from accessing underlying tables directly and enforcing consistent security policies.", "Applicability": [ "tlp-red", "tlp-amber" @@ -890,15 +845,15 @@ "Checks": [] }, { - "Id": "CCC.DataWar.C02.TR01", - "Description": "Attempt to query sensitive columns without the necessary permissions and\nverify that access is denied or data is masked.", + "Id": "CCC.DataWar.CN02.AR01", + "Description": "Attempt to query sensitive columns without the necessary permissions and verify that access is denied or data is masked.", "Attributes": [ { "FamilyName": "Data", "FamilyDescription": "TODO: Describe this control family", - "Section": "CCC.DataWar.C02 Enforce Column-Level Security Policies", + "Section": "CCC.DataWar.CN02 Enforce Column-Level Security Policies", "SubSection": "", - "SubSectionObjective": "Ensure that access to sensitive data columns is restricted based on user roles,\npreventing unauthorized access to sensitive information.", + "SubSectionObjective": "Ensure that access to sensitive data columns is restricted based on user roles, preventing unauthorized access to sensitive information.", "Applicability": [ "tlp-red", "tlp-amber" @@ -932,15 +887,15 @@ "Checks": [] }, { - "Id": "CCC.DataWar.C03.TR01", - "Description": "Attempt to query data rows that the user should not have access to and verify\nthat access is denied or data is not returned.", + "Id": "CCC.DataWar.CN03.AR01", + "Description": "Attempt to query data rows that the user should not have access to and verify that access is denied or data is not returned.", "Attributes": [ { "FamilyName": "Data", "FamilyDescription": "TODO: Describe this control family", - "Section": "CCC.DataWar.C03 Enforce Row-Level Security Policies", + "Section": "CCC.DataWar.CN03 Enforce Row-Level Security Policies", "SubSection": "", - "SubSectionObjective": "Ensure that access to data rows is restricted based on user roles or attributes,\npreventing unauthorized access to specific subsets of data.", + "SubSectionObjective": "Ensure that access to data rows is restricted based on user roles or attributes, preventing unauthorized access to specific subsets of data.", "Applicability": [ "tlp-red", "tlp-amber" @@ -980,684 +935,13 @@ ] }, { - "Id": "CCC.GenAI.C01.TR01", - "Description": "Untrusted input such as user queries, RAG data or tool output\nMUST be validated before it is passed to a GenAI model.", - "Attributes": [ - { - "FamilyName": "Data", - "FamilyDescription": "The Data control family ensures the confidentiality, integrity,\navailability, and sovereignty of data across its lifecycle.\nThese controls govern how data is transmitted, stored,\nreplicated, and protected from unauthorized access, tampering,\nor exposure beyond defined trust perimeters.\n", - "Section": "CCC.GenAI.C01 Model Input Filtering and Sanitisation", - "SubSection": "", - "SubSectionObjective": "Inspect and validate input before it is passed to a GenAI\nmodel in order to filter or sanitise adversarial queries\nand prevent sensitive data leakage.", - "Applicability": [ - "tlp-clear", - "tlp-green", - "tlp-amber", - "tlp-red" - ], - "Recommendation": "", - "SectionThreatMappings": [ - { - "ReferenceId": "CCC", - "Identifiers": [ - "CCC.GenAI.TH01", - "CCC.GenAI.TH03" - ] - } - ], - "SectionGuidelineMappings": [ - { - "ReferenceId": "FINOS-AIGF", - "Identifiers": [ - "AIR-PREV-003", - "AIR-PREV-017", - "AIR-PREV-002", - "AIR-DET-001" - ] - }, - { - "ReferenceId": "SAIF", - "Identifiers": [ - "Input Validation and Sanitization" - ] - }, - { - "ReferenceId": "MITRE-ATLAS", - "Identifiers": [ - "AML.M0020", - "AML.M0021", - "AML.M0015" - ] - } - ] - } - ], - "Checks": [] - }, - { - "Id": "CCC.GenAI.C01.TR02", - "Description": "If malicious patterns such as prompt injection or sensitive\ndata are detected during input validation, the input MUST\nbe blocked or sanitised.", - "Attributes": [ - { - "FamilyName": "Data", - "FamilyDescription": "The Data control family ensures the confidentiality, integrity,\navailability, and sovereignty of data across its lifecycle.\nThese controls govern how data is transmitted, stored,\nreplicated, and protected from unauthorized access, tampering,\nor exposure beyond defined trust perimeters.\n", - "Section": "CCC.GenAI.C01 Model Input Filtering and Sanitisation", - "SubSection": "", - "SubSectionObjective": "Inspect and validate input before it is passed to a GenAI\nmodel in order to filter or sanitise adversarial queries\nand prevent sensitive data leakage.", - "Applicability": [ - "tlp-clear", - "tlp-green", - "tlp-amber", - "tlp-red" - ], - "Recommendation": "", - "SectionThreatMappings": [ - { - "ReferenceId": "CCC", - "Identifiers": [ - "CCC.GenAI.TH01", - "CCC.GenAI.TH03" - ] - } - ], - "SectionGuidelineMappings": [ - { - "ReferenceId": "FINOS-AIGF", - "Identifiers": [ - "AIR-PREV-003", - "AIR-PREV-017", - "AIR-PREV-002", - "AIR-DET-001" - ] - }, - { - "ReferenceId": "SAIF", - "Identifiers": [ - "Input Validation and Sanitization" - ] - }, - { - "ReferenceId": "MITRE-ATLAS", - "Identifiers": [ - "AML.M0020", - "AML.M0021", - "AML.M0015" - ] - } - ] - } - ], - "Checks": [] - }, - { - "Id": "CCC.GenAI.C02.TR01", - "Description": "GenAI model output MUST be validated for format conformance,\nmalicious patterns, sensitive data and inapropriate content\nbefore being passed to users, application or plugins.", - "Attributes": [ - { - "FamilyName": "Data", - "FamilyDescription": "The Data control family ensures the confidentiality, integrity,\navailability, and sovereignty of data across its lifecycle.\nThese controls govern how data is transmitted, stored,\nreplicated, and protected from unauthorized access, tampering,\nor exposure beyond defined trust perimeters.\n", - "Section": "CCC.GenAI.C02 Model Output Filtering and Sanitisation", - "SubSection": "", - "SubSectionObjective": "Inspect and validate GenAI model output before passing it to\nusers, applications or plugins in order to filter or sanitise\ninsecure or unreliable output and prevent sensitive data leakage.", - "Applicability": [ - "tlp-clear", - "tlp-green", - "tlp-amber", - "tlp-red" - ], - "Recommendation": "", - "SectionThreatMappings": [ - { - "ReferenceId": "CCC", - "Identifiers": [ - "CCC.GenAI.TH01", - "CCC.GenAI.TH03", - "CCC.GenAI.TH04", - "CCC.GenAI.TH05", - "CCC.GenAI.TH06" - ] - } - ], - "SectionGuidelineMappings": [ - { - "ReferenceId": "FINOS-AIGF", - "Identifiers": [ - "AIR-PREV-003", - "AIR-PREV-017", - "AIR-PREV-002", - "AIR-DET-001" - ] - }, - { - "ReferenceId": "SAIF", - "Identifiers": [ - "Output Validation and Sanitization" - ] - }, - { - "ReferenceId": "MITRE-ATLAS", - "Identifiers": [ - "AML.M0020", - "AML.M0002" - ] - } - ] - } - ], - "Checks": [] - }, - { - "Id": "CCC.GenAI.C02.TR02", - "Description": "In the event of policy violations, the AI-generated content MUST\nbe redacted, encoded or rejected.", - "Attributes": [ - { - "FamilyName": "Data", - "FamilyDescription": "The Data control family ensures the confidentiality, integrity,\navailability, and sovereignty of data across its lifecycle.\nThese controls govern how data is transmitted, stored,\nreplicated, and protected from unauthorized access, tampering,\nor exposure beyond defined trust perimeters.\n", - "Section": "CCC.GenAI.C02 Model Output Filtering and Sanitisation", - "SubSection": "", - "SubSectionObjective": "Inspect and validate GenAI model output before passing it to\nusers, applications or plugins in order to filter or sanitise\ninsecure or unreliable output and prevent sensitive data leakage.", - "Applicability": [ - "tlp-clear", - "tlp-green", - "tlp-amber", - "tlp-red" - ], - "Recommendation": "", - "SectionThreatMappings": [ - { - "ReferenceId": "CCC", - "Identifiers": [ - "CCC.GenAI.TH01", - "CCC.GenAI.TH03", - "CCC.GenAI.TH04", - "CCC.GenAI.TH05", - "CCC.GenAI.TH06" - ] - } - ], - "SectionGuidelineMappings": [ - { - "ReferenceId": "FINOS-AIGF", - "Identifiers": [ - "AIR-PREV-003", - "AIR-PREV-017", - "AIR-PREV-002", - "AIR-DET-001" - ] - }, - { - "ReferenceId": "SAIF", - "Identifiers": [ - "Output Validation and Sanitization" - ] - }, - { - "ReferenceId": "MITRE-ATLAS", - "Identifiers": [ - "AML.M0020", - "AML.M0002" - ] - } - ] - } - ], - "Checks": [ - "apim_threat_detection_llm_jacking" - ] - }, - { - "Id": "CCC.GenAI.C03.TR01", - "Description": "When data is designated for model training or RAG ingestion, then its\nsource MUST be explicitly approved and its provenance documented.", - "Attributes": [ - { - "FamilyName": "Data", - "FamilyDescription": "The Data control family ensures the confidentiality, integrity,\navailability, and sovereignty of data across its lifecycle.\nThese controls govern how data is transmitted, stored,\nreplicated, and protected from unauthorized access, tampering,\nor exposure beyond defined trust perimeters.\n", - "Section": "CCC.GenAI.C03 Data Provenance and Source Vetting", - "SubSection": "", - "SubSectionObjective": "Ensure that all data for training, fine-tuning or RAG comes\nfrom trusted, approved sources and is authorised for the\nintended purposes in order to prevent the initial introduction\nof malicious content or leaked sensitive data.", - "Applicability": [ - "tlp-clear", - "tlp-green", - "tlp-amber", - "tlp-red" - ], - "Recommendation": "", - "SectionThreatMappings": [ - { - "ReferenceId": "CCC", - "Identifiers": [ - "CCC.GenAI.TH02", - "CCC.GenAI.TH03" - ] - } - ], - "SectionGuidelineMappings": [ - { - "ReferenceId": "FINOS-AIGF", - "Identifiers": [ - "AIR-PREV-006" - ] - }, - { - "ReferenceId": "SAIF", - "Identifiers": [ - "Training Data Management" - ] - }, - { - "ReferenceId": "MITRE-ATLAS", - "Identifiers": [ - "AML.M0025" - ] - } - ] - } - ], - "Checks": [] - }, - { - "Id": "CCC.GenAI.C03.TR02", - "Description": "Data from unvetted sources MUST NOT be used in production systems.", - "Attributes": [ - { - "FamilyName": "Data", - "FamilyDescription": "The Data control family ensures the confidentiality, integrity,\navailability, and sovereignty of data across its lifecycle.\nThese controls govern how data is transmitted, stored,\nreplicated, and protected from unauthorized access, tampering,\nor exposure beyond defined trust perimeters.\n", - "Section": "CCC.GenAI.C03 Data Provenance and Source Vetting", - "SubSection": "", - "SubSectionObjective": "Ensure that all data for training, fine-tuning or RAG comes\nfrom trusted, approved sources and is authorised for the\nintended purposes in order to prevent the initial introduction\nof malicious content or leaked sensitive data.", - "Applicability": [ - "tlp-clear", - "tlp-green", - "tlp-amber", - "tlp-red" - ], - "Recommendation": "", - "SectionThreatMappings": [ - { - "ReferenceId": "CCC", - "Identifiers": [ - "CCC.GenAI.TH02", - "CCC.GenAI.TH03" - ] - } - ], - "SectionGuidelineMappings": [ - { - "ReferenceId": "FINOS-AIGF", - "Identifiers": [ - "AIR-PREV-006" - ] - }, - { - "ReferenceId": "SAIF", - "Identifiers": [ - "Training Data Management" - ] - }, - { - "ReferenceId": "MITRE-ATLAS", - "Identifiers": [ - "AML.M0025" - ] - } - ] - } - ], - "Checks": [] - }, - { - "Id": "CCC.GenAI.C04.TR01", - "Description": "When data is ingested for training, fine-tuning or conversion\nto vector embeddings, it MUST be validated for sensitive\ninformation or malicious content.", - "Attributes": [ - { - "FamilyName": "Data", - "FamilyDescription": "The Data control family ensures the confidentiality, integrity,\navailability, and sovereignty of data across its lifecycle.\nThese controls govern how data is transmitted, stored,\nreplicated, and protected from unauthorized access, tampering,\nor exposure beyond defined trust perimeters.\n", - "Section": "CCC.GenAI.C04 Sanitisation of Ingested Data", - "SubSection": "", - "SubSectionObjective": "Validate and sanitise all data ingested by GenAI systems\nfrom extenal sources or internal knowledge bases, whether\nfor training, conversion to vector embeddings, or real-time\nretireval, in order to remove or redact poisoned or sensitive\ndata before further processing.", - "Applicability": [ - "tlp-clear", - "tlp-green", - "tlp-amber", - "tlp-red" - ], - "Recommendation": "", - "SectionThreatMappings": [ - { - "ReferenceId": "CCC", - "Identifiers": [ - "CCC.GenAI.TH02", - "CCC.GenAI.TH03" - ] - } - ], - "SectionGuidelineMappings": [ - { - "ReferenceId": "FINOS-AIGF", - "Identifiers": [ - "AIR-PREV-002" - ] - }, - { - "ReferenceId": "SAIF", - "Identifiers": [ - "Training Data Sanitization" - ] - }, - { - "ReferenceId": "MITRE-ATLAS", - "Identifiers": [ - "AML.M0007" - ] - } - ] - } - ], - "Checks": [] - }, - { - "Id": "CCC.GenAI.C04.TR02", - "Description": "If sensitive data or malicious content is detected, it must\nbe rejected, redacted or flagged for manual review.", - "Attributes": [ - { - "FamilyName": "Data", - "FamilyDescription": "The Data control family ensures the confidentiality, integrity,\navailability, and sovereignty of data across its lifecycle.\nThese controls govern how data is transmitted, stored,\nreplicated, and protected from unauthorized access, tampering,\nor exposure beyond defined trust perimeters.\n", - "Section": "CCC.GenAI.C04 Sanitisation of Ingested Data", - "SubSection": "", - "SubSectionObjective": "Validate and sanitise all data ingested by GenAI systems\nfrom extenal sources or internal knowledge bases, whether\nfor training, conversion to vector embeddings, or real-time\nretireval, in order to remove or redact poisoned or sensitive\ndata before further processing.", - "Applicability": [ - "tlp-clear", - "tlp-green", - "tlp-amber", - "tlp-red" - ], - "Recommendation": "", - "SectionThreatMappings": [ - { - "ReferenceId": "CCC", - "Identifiers": [ - "CCC.GenAI.TH02", - "CCC.GenAI.TH03" - ] - } - ], - "SectionGuidelineMappings": [ - { - "ReferenceId": "FINOS-AIGF", - "Identifiers": [ - "AIR-PREV-002" - ] - }, - { - "ReferenceId": "SAIF", - "Identifiers": [ - "Training Data Sanitization" - ] - }, - { - "ReferenceId": "MITRE-ATLAS", - "Identifiers": [ - "AML.M0007" - ] - } - ] - } - ], - "Checks": [] - }, - { - "Id": "CCC.GenAI.C05.TR01", - "Description": "When a RAG-enabled system generates a response containing information\nretrieved from its knowledge base, then the response MUST include a\nverifiable citation that links back to the specific source document.", - "Attributes": [ - { - "FamilyName": "Data", - "FamilyDescription": "The Data control family ensures the confidentiality, integrity,\navailability, and sovereignty of data across its lifecycle.\nThese controls govern how data is transmitted, stored,\nreplicated, and protected from unauthorized access, tampering,\nor exposure beyond defined trust perimeters.\n", - "Section": "CCC.GenAI.C05 Citations and Source Traceability", - "SubSection": "", - "SubSectionObjective": "Require the GenAI system to provide citations or direct links\nback to the source documents used to generate a response, in\nto enhance the transparency, trustworthiness, and verifiability\nof AI-generated content.", - "Applicability": [ - "tlp-clear", - "tlp-green", - "tlp-amber", - "tlp-red" - ], - "Recommendation": "", - "SectionThreatMappings": [ - { - "ReferenceId": "CCC", - "Identifiers": [ - "CCC.GenAI.TH09", - "CCC.GenAI.TH04" - ] - } - ], - "SectionGuidelineMappings": [ - { - "ReferenceId": "FINOS-AIGF", - "Identifiers": [ - "AIR-DET-013" - ] - } - ] - } - ], - "Checks": [ - "monitor_diagnostic_settings_exists", - "monitor_diagnostic_setting_with_appropriate_categories", - "keyvault_logging_enabled", - "app_http_logs_enabled", - "app_function_application_insights_enabled", - "appinsights_ensure_is_configured", - "monitor_alert_service_health_exists", - "sqlserver_auditing_enabled", - "sqlserver_auditing_retention_90_days", - "mysql_flexible_server_audit_log_enabled" - ] - }, - { - "Id": "CCC.GenAI.C06.TR01", - "Description": "When an LLM invokes an external tool (e.g., an API, a plugin),\nthen the tool MUST operate with the least privileges required\nfor performing its intended functionality.", - "Attributes": [ - { - "FamilyName": "Identity and Access Management", - "FamilyDescription": "The Identity and Access Management control family ensures\nthat only trusted and authenticated entities can access\nresources. These controls establish strong authentication,\nenforce multi-factor verification, and restrict access to\napproved sources to prevent unauthorized use or data exfiltration.\n", - "Section": "CCC.GenAI.C06 Least Privilege for Plugins", - "SubSection": "", - "SubSectionObjective": "Restricts the permissions of any external tools the GenAI system\ncan call to limit the potential damage if an agent is coerced\nto perform unintended actions or vulnerabilities in the tools\nare exploited.", - "Applicability": [ - "tlp-clear", - "tlp-green", - "tlp-amber", - "tlp-red" - ], - "Recommendation": "", - "SectionThreatMappings": [ - { - "ReferenceId": "CCC", - "Identifiers": [ - "CCC.GenAI.TH07", - "CCC.GenAI.TH06" - ] - } - ], - "SectionGuidelineMappings": [ - { - "ReferenceId": "SAIF", - "Identifiers": [ - "Agent Permissions" - ] - } - ] - } - ], - "Checks": [ - "iam_custom_role_has_permissions_to_administer_resource_locks", - "iam_subscription_roles_owner_custom_not_created", - "iam_role_user_access_admin_restricted", - "app_function_identity_without_admin_privileges", - "app_function_identity_is_configured", - "cosmosdb_account_use_aad_and_rbac" - ] - }, - { - "Id": "CCC.GenAI.C07.TR01", - "Description": "When an application makes an API call to a foundational model in a\nproduction environment, then it MUST specify an explicit version\nidentifier.", - "Attributes": [ - { - "FamilyName": "Configuration Management", - "FamilyDescription": "The Configuration Management control family involves establishing,\nmaintaining and monitoring the configuration of the service and\nrelated applications and infrastructure to ensure consistency,\nsecure defaults and compliance.\n", - "Section": "CCC.GenAI.C07 Model Version Pinning", - "SubSection": "", - "SubSectionObjective": "Mandate that applications are locked (\"pinned\") to a specific,\ntested version of a foundational model to prevent unexpected\nbehaviour changes introduced by provider-side updates.", - "Applicability": [ - "tlp-clear", - "tlp-green", - "tlp-amber", - "tlp-red" - ], - "Recommendation": "", - "SectionThreatMappings": [ - { - "ReferenceId": "CCC", - "Identifiers": [ - "CCC.GenAI.TH10" - ] - } - ], - "SectionGuidelineMappings": [ - { - "ReferenceId": "FINOS-AIGF", - "Identifiers": [ - "AIR-PREV-010" - ] - } - ] - } - ], - "Checks": [] - }, - { - "Id": "CCC.GenAI.C08.TR01", - "Description": "When a new AI model is considered for production deployment, it\nMUST undergo a formal red teaming and quality assurance review.", - "Attributes": [ - { - "FamilyName": "Model Assurance and Evaluation", - "FamilyDescription": "The Model Assurance and Evaluation control family encompasses\nthe proactiveand continuous processes of testing and validating\nthe AI model's behavior to ensure it aligns with safety, ethical,\nand quality standards.\n", - "Section": "CCC.GenAI.C08 Quality Control and Red Teaming", - "SubSection": "", - "SubSectionObjective": "Establish a formal program for quality evaluation and adversarial\ntesting (red teaming) to ensure GenAI system meet all business,\nquality, security and compliance requirements before getting deployed\ninto production environments.", - "Applicability": [ - "tlp-clear", - "tlp-green", - "tlp-amber", - "tlp-red" - ], - "Recommendation": "", - "SectionThreatMappings": [ - { - "ReferenceId": "CCC", - "Identifiers": [ - "CCC.GenAI.TH01", - "CCC.GenAI.TH02", - "CCC.GenAI.TH04", - "CCC.GenAI.TH08", - "CCC.GenAI.TH10" - ] - } - ], - "SectionGuidelineMappings": [ - { - "ReferenceId": "FINOS-AIGF", - "Identifiers": [ - "AIR-PREV-005" - ] - }, - { - "ReferenceId": "SAIF", - "Identifiers": [ - "Adversarial Training and Testing", - "Red Teaming", - "Product Governance" - ] - }, - { - "ReferenceId": "MITRE-ATLAS", - "Identifiers": [ - "AML.M0008" - ] - } - ] - } - ], - "Checks": [ - "apim_threat_detection_llm_jacking" - ] - }, - { - "Id": "CCC.GenAI.C08.TR02", - "Description": "If model quality review or red teaming identifies an issue that exceeds\nthe organization's risk tolerance, the model MUST NOT be deployed until\nthe issue is remediated.", - "Attributes": [ - { - "FamilyName": "Model Assurance and Evaluation", - "FamilyDescription": "The Model Assurance and Evaluation control family encompasses\nthe proactiveand continuous processes of testing and validating\nthe AI model's behavior to ensure it aligns with safety, ethical,\nand quality standards.\n", - "Section": "CCC.GenAI.C08 Quality Control and Red Teaming", - "SubSection": "", - "SubSectionObjective": "Establish a formal program for quality evaluation and adversarial\ntesting (red teaming) to ensure GenAI system meet all business,\nquality, security and compliance requirements before getting deployed\ninto production environments.", - "Applicability": [ - "tlp-clear", - "tlp-green", - "tlp-amber", - "tlp-red" - ], - "Recommendation": "", - "SectionThreatMappings": [ - { - "ReferenceId": "CCC", - "Identifiers": [ - "CCC.GenAI.TH01", - "CCC.GenAI.TH02", - "CCC.GenAI.TH04", - "CCC.GenAI.TH08", - "CCC.GenAI.TH10" - ] - } - ], - "SectionGuidelineMappings": [ - { - "ReferenceId": "FINOS-AIGF", - "Identifiers": [ - "AIR-PREV-005" - ] - }, - { - "ReferenceId": "SAIF", - "Identifiers": [ - "Adversarial Training and Testing", - "Red Teaming", - "Product Governance" - ] - }, - { - "ReferenceId": "MITRE-ATLAS", - "Identifiers": [ - "AML.M0008" - ] - } - ] - } - ], - "Checks": [ - "apim_threat_detection_llm_jacking" - ] - }, - { - "Id": "CCC.KeyMgmt.C01.TR01", - "Description": "When a key version is scheduled for deletion or disabled, an\nalert MUST be generated within five minutes.", + "Id": "CCC.KeyMgmt.CN01.AR01", + "Description": "When a key version is scheduled for deletion or disabled, an alert MUST be generated within five minutes.", "Attributes": [ { "FamilyName": "Logging and Metrics Publication", "FamilyDescription": "Controls that collect, alert, and retain key-management events.", - "Section": "CCC.KeyMgmt.C01 Alert on Key-version Changes", + "Section": "CCC.KeyMgmt.CN01 Alert on Key-version Changes", "SubSection": "", "SubSectionObjective": "Generate near-real-time alerts when a KMS key version is disabled or scheduled for deletion, enabling rapid investigation and recovery.", "Applicability": [ @@ -1700,13 +984,13 @@ ] }, { - "Id": "CCC.KeyMgmt.C02.TR01", - "Description": "When IAM roles and key policies are reviewed, Decrypt permission\nMUST be granted exclusively to documented authorised principals.", + "Id": "CCC.KeyMgmt.CN02.AR01", + "Description": "When IAM roles and key policies are reviewed, Decrypt permission MUST be granted exclusively to documented authorised principals.", "Attributes": [ { "FamilyName": "Identity and Access Management", "FamilyDescription": "Controls that enforce least-privilege use of KMS operations.", - "Section": "CCC.KeyMgmt.C02 Limit Decrypt Permissions", + "Section": "CCC.KeyMgmt.CN02 Limit Decrypt Permissions", "SubSection": "", "SubSectionObjective": "Restrict the Decrypt operation to authorised principals only, applying the principle of least privilege to protect sensitive data.", "Applicability": [ @@ -1745,13 +1029,13 @@ ] }, { - "Id": "CCC.KeyMgmt.C03.TR01", - "Description": "When rotation settings are examined, rotation MUST be enabled with\nan interval not exceeding 365 days.", + "Id": "CCC.KeyMgmt.CN03.AR01", + "Description": "When rotation settings are examined, rotation MUST be enabled with an interval not exceeding 365 days.", "Attributes": [ { "FamilyName": "Key Lifecycle Management", "FamilyDescription": "Controls that govern creation, rotation, import, and retirement of cryptographic keys.", - "Section": "CCC.KeyMgmt.C03 Enforce Automatic Rotation", + "Section": "CCC.KeyMgmt.CN03 Enforce Automatic Rotation", "SubSection": "", "SubSectionObjective": "Ensure symmetric keys rotate automatically within policy intervals to reduce exposure of key material.", "Applicability": [ @@ -1787,13 +1071,13 @@ ] }, { - "Id": "CCC.KeyMgmt.C04.TR01", - "Description": "When a key import request is processed, the key MUST use an\napproved algorithm (RSA-2048+, EC-P256+) and originate from a\ncertified HSM.", + "Id": "CCC.KeyMgmt.CN04.AR01", + "Description": "When a key import request is processed, the key MUST use an approved algorithm (RSA-2048+, EC-P256+) and originate from a certified HSM.", "Attributes": [ { "FamilyName": "Key Lifecycle Management", "FamilyDescription": "Controls that govern creation, rotation, import, and retirement of cryptographic keys.", - "Section": "CCC.KeyMgmt.C04 Validate Imported Keys", + "Section": "CCC.KeyMgmt.CN04 Validate Imported Keys", "SubSection": "", "SubSectionObjective": "Accept only externally generated keys that meet approved cryptographic strength and provenance requirements.", "Applicability": [ @@ -1838,13 +1122,13 @@ ] }, { - "Id": "CCC.LB.C01.TR01", - "Description": "When a single client sends more than 2000 requests within any\n5-minute sliding window, the load balancer MUST throttle all\nsubsequent requests from that client for at least 60 seconds.", + "Id": "CCC.LB.CN01.AR01", + "Description": "When a single client sends more than 2000 requests within any 5-minute sliding window, the load balancer MUST throttle all subsequent requests from that client for at least 60 seconds.", "Attributes": [ { "FamilyName": "Logging & Monitoring", - "FamilyDescription": "Controls that detect anomalous traffic and record load-balancer activity.\n", - "Section": "CCC.LB.C01 Enforce and Detect Rate Limiting", + "FamilyDescription": "Controls that detect anomalous traffic and record load-balancer activity. ", + "Section": "CCC.LB.CN01 Enforce and Detect Rate Limiting", "SubSection": "", "SubSectionObjective": "Detect and throttle malicious or excessive requests to prevent downstream resource exhaustion and brute-force activity.", "Applicability": [ @@ -1852,7 +1136,7 @@ "tlp-amber", "tlp-red" ], - "Recommendation": "Implement per-IP token-bucket limits with and verify via\nsynthetic traffic tests.\n", + "Recommendation": "Implement per-IP token-bucket limits with and verify via synthetic traffic tests. ", "SectionThreatMappings": [ { "ReferenceId": "LB", @@ -1885,13 +1169,13 @@ "Checks": [] }, { - "Id": "CCC.LB.C01.TR02", - "Description": "When throttling is invoked, the load balancer MUST\nrecord the event in the access log within 5 minutes\nfor alerting and trend analysis.", + "Id": "CCC.LB.CN01.AR02", + "Description": "When throttling is invoked, the load balancer MUST record the event in the access log within 5 minutes for alerting and trend analysis.", "Attributes": [ { "FamilyName": "Logging & Monitoring", - "FamilyDescription": "Controls that detect anomalous traffic and record load-balancer activity.\n", - "Section": "CCC.LB.C01 Enforce and Detect Rate Limiting", + "FamilyDescription": "Controls that detect anomalous traffic and record load-balancer activity. ", + "Section": "CCC.LB.CN01 Enforce and Detect Rate Limiting", "SubSection": "", "SubSectionObjective": "Detect and throttle malicious or excessive requests to prevent downstream resource exhaustion and brute-force activity.", "Applicability": [ @@ -1899,7 +1183,7 @@ "tlp-amber", "tlp-red" ], - "Recommendation": "Enable access logging and configure metric filters\non HTTP 429 counts to trigger alerts.\n", + "Recommendation": "Enable access logging and configure metric filters on HTTP 429 counts to trigger alerts. ", "SectionThreatMappings": [ { "ReferenceId": "LB", @@ -1939,21 +1223,21 @@ ] }, { - "Id": "CCC.LB.C06.TR01", - "Description": "When more than 10 percent of targets change from healthy to\nunhealthy within five minutes, an alert MUST be issued.", + "Id": "CCC.LB.CN06.AR01", + "Description": "When more than 10 percent of targets change from healthy to unhealthy within five minutes, an alert MUST be issued.", "Attributes": [ { "FamilyName": "Logging & Monitoring", - "FamilyDescription": "Controls that detect anomalous traffic and record load-balancer activity.\n", - "Section": "CCC.LB.C06 Secure Health-Check Telemetry", + "FamilyDescription": "Controls that detect anomalous traffic and record load-balancer activity. ", + "Section": "CCC.LB.CN06 Secure Health-Check Telemetry", "SubSection": "", - "SubSectionObjective": "Monitor health-check endpoints for tampering and alert on\nabnormal status changes.", + "SubSectionObjective": "Monitor health-check endpoints for tampering and alert on abnormal status changes.", "Applicability": [ "tlp-green", "tlp-amber", "tlp-red" ], - "Recommendation": "Instrument metrics for health check results and target\nremoval events. Configure monitoring alarms to alert\non abnormal spikes in unhealthy targets.\n", + "Recommendation": "Instrument metrics for health check results and target removal events. Configure monitoring alarms to alert on abnormal spikes in unhealthy targets. ", "SectionThreatMappings": [ { "ReferenceId": "LB", @@ -1992,21 +1276,21 @@ ] }, { - "Id": "CCC.LB.C04.TR01", - "Description": "When routing weights change, the request MUST originate\nfrom an explicitly defined and trusted identity and MUST\nbe logged.", + "Id": "CCC.LB.CN04.AR01", + "Description": "When routing weights change, the request MUST originate from an explicitly defined and trusted identity and MUST be logged.", "Attributes": [ { "FamilyName": "Identity and Access Management", - "FamilyDescription": "Controls that restrict who can change or query load-balancer resources.\n", - "Section": "CCC.LB.C04 Enforce Distribution Policies", + "FamilyDescription": "Controls that restrict who can change or query load-balancer resources. ", + "Section": "CCC.LB.CN04 Enforce Distribution Policies", "SubSection": "", - "SubSectionObjective": "Ensure traffic-splitting weights and algorithms are modified\nonly by trusted identities.", + "SubSectionObjective": "Ensure traffic-splitting weights and algorithms are modified only by trusted identities.", "Applicability": [ "tlp-green", "tlp-amber", "tlp-red" ], - "Recommendation": "Define a list of trusted principals allowed to modify\nrouting configurations. Enforce via conditional access\npolicies, and log changes using audit logging.\n", + "Recommendation": "Define a list of trusted principals allowed to modify routing configurations. Enforce via conditional access policies, and log changes using audit logging. ", "SectionThreatMappings": [ { "ReferenceId": "LB", @@ -2044,15 +1328,15 @@ ] }, { - "Id": "CCC.LB.C05.TR01", - "Description": "When stickiness is enabled, session cookies MUST expire\nwithin 30 minutes of inactivity.", + "Id": "CCC.LB.CN05.AR01", + "Description": "When stickiness is enabled, session cookies MUST expire within 30 minutes of inactivity.", "Attributes": [ { "FamilyName": "Identity and Access Management", - "FamilyDescription": "Controls that restrict who can change or query load-balancer resources.\n", - "Section": "CCC.LB.C05 Validate Session Affinity", + "FamilyDescription": "Controls that restrict who can change or query load-balancer resources. ", + "Section": "CCC.LB.CN05 Validate Session Affinity", "SubSection": "", - "SubSectionObjective": "Configure session persistence to minimise fixation and hijacking\nrisks.", + "SubSectionObjective": "Configure session persistence to minimise fixation and hijacking risks.", "Applicability": [ "tlp-green", "tlp-amber", @@ -2090,15 +1374,15 @@ ] }, { - "Id": "CCC.LB.C09.TR01", - "Description": "When an API call originates outside the approved CIDR\nset, the request MUST be denied.", + "Id": "CCC.LB.CN09.AR01", + "Description": "When an API call originates outside the approved CIDR set, the request MUST be denied.", "Attributes": [ { "FamilyName": "Identity and Access Management", - "FamilyDescription": "Controls that restrict who can change or query load-balancer resources.\n", - "Section": "CCC.LB.C09 Restrict Management API Access", + "FamilyDescription": "Controls that restrict who can change or query load-balancer resources. ", + "Section": "CCC.LB.CN09 Restrict Management API Access", "SubSection": "", - "SubSectionObjective": "Limit load-balancer API calls to authorised identities and\ntrusted networks.", + "SubSectionObjective": "Limit load-balancer API calls to authorised identities and trusted networks.", "Applicability": [ "tlp-green", "tlp-amber", @@ -2138,15 +1422,15 @@ ] }, { - "Id": "CCC.LB.C02.TR01", - "Description": "When concurrent connections reach 80 percent of capacity, the\nautoscaling group MUST add at least one instance within five\nminutes.", + "Id": "CCC.LB.CN02.AR01", + "Description": "When concurrent connections reach 80 percent of capacity, the autoscaling group MUST add at least one instance within five minutes.", "Attributes": [ { "FamilyName": "Data", - "FamilyDescription": "Controls that preserve availability and confidentiality of\ntraffic processed by the load balancer.\n", - "Section": "CCC.LB.C02 Auto-Scale Load Balancer Capacity", + "FamilyDescription": "Controls that preserve availability and confidentiality of traffic processed by the load balancer. ", + "Section": "CCC.LB.CN02 Auto-Scale Load Balancer Capacity", "SubSection": "", - "SubSectionObjective": "Expand load-balancer capacity to maintain availability during traffic\nspikes.", + "SubSectionObjective": "Expand load-balancer capacity to maintain availability during traffic spikes.", "Applicability": [ "tlp-green", "tlp-amber", @@ -2180,15 +1464,15 @@ "Checks": [] }, { - "Id": "CCC.LB.C07.TR01", - "Description": "When responses pass through the load balancer, the\n\"Server\" header MUST be replaced with \"lb\".", + "Id": "CCC.LB.CN07.AR01", + "Description": "When responses pass through the load balancer, the \"Server\" header MUST be replaced with \"lb\".", "Attributes": [ { "FamilyName": "Data", - "FamilyDescription": "Controls that preserve availability and confidentiality of\ntraffic processed by the load balancer.\n", - "Section": "CCC.LB.C07 Scrub Sensitive Headers", + "FamilyDescription": "Controls that preserve availability and confidentiality of traffic processed by the load balancer. ", + "Section": "CCC.LB.CN07 Scrub Sensitive Headers", "SubSection": "", - "SubSectionObjective": "Remove headers that disclose internal details or software\nversions from HTTP responses.", + "SubSectionObjective": "Remove headers that disclose internal details or software versions from HTTP responses.", "Applicability": [ "tlp-green", "tlp-amber", @@ -2222,15 +1506,15 @@ "Checks": [] }, { - "Id": "CCC.LB.C08.TR01", - "Description": "When a certificate is within 30 days of expiry, automated renewal\nMUST complete and deploy a new certificate within 24 hours.", + "Id": "CCC.LB.CN08.AR01", + "Description": "When a certificate is within 30 days of expiry, automated renewal MUST complete and deploy a new certificate within 24 hours.", "Attributes": [ { "FamilyName": "Encryption", "FamilyDescription": "Controls that ensure trustworthy TLS certificates and ciphers.", - "Section": "CCC.LB.C08 Automate Certificate Renewal", + "Section": "CCC.LB.CN08 Automate Certificate Renewal", "SubSection": "", - "SubSectionObjective": "Maintain valid TLS certificates by automating renewal and\ndeployment before expiry.", + "SubSectionObjective": "Maintain valid TLS certificates by automating renewal and deployment before expiry.", "Applicability": [ "tlp-green", "tlp-amber", @@ -2261,21 +1545,18 @@ ] } ], - "Checks": [ - "app_minimum_tls_version_12", - "storage_ensure_minimum_tls_version_12" - ] + "Checks": [] }, { - "Id": "CCC.Logging.C01.TR01", - "Description": "When a new cloud account is created, provider-level audit and network flow logging MUST be\nenabled by default and directed to the central sink.", + "Id": "CCC.Logging.CN01.AR01", + "Description": "When a new cloud account is created, provider-level audit and network flow logging MUST be enabled by default and directed to the central sink.", "Attributes": [ { "FamilyName": "Data", - "FamilyDescription": "Controls related to the confidentiality, integrity and availability of log data.\n", - "Section": "CCC.Logging.C01 Centralized and Comprehensive Log Aggregation", + "FamilyDescription": "Controls related to the confidentiality, integrity and availability of log data. ", + "Section": "CCC.Logging.CN01 Centralized and Comprehensive Log Aggregation", "SubSection": "", - "SubSectionObjective": "Ensure all operational and security logs from across the cloud environment, including\napplications, operating systems, network traffic, and cloud service activity, are captured\nautomatically and streamed to a central, secure log management service.", + "SubSectionObjective": "Ensure all operational and security logs from across the cloud environment, including applications, operating systems, network traffic, and cloud service activity, are captured automatically and streamed to a central, secure log management service.", "Applicability": [ "tlp-clear", "tlp-green", @@ -2317,15 +1598,15 @@ ] }, { - "Id": "CCC.Logging.C01.TR02", - "Description": "When a new cloud compute resource is deployed, it MUST be configured to forward all relevant\nlogs (e.g., OS, application, service logs) to the central log sink.", + "Id": "CCC.Logging.CN01.AR02", + "Description": "When a new cloud compute resource is deployed, it MUST be configured to forward all relevant logs (e.g., OS, application, service logs) to the central log sink.", "Attributes": [ { "FamilyName": "Data", - "FamilyDescription": "Controls related to the confidentiality, integrity and availability of log data.\n", - "Section": "CCC.Logging.C01 Centralized and Comprehensive Log Aggregation", + "FamilyDescription": "Controls related to the confidentiality, integrity and availability of log data. ", + "Section": "CCC.Logging.CN01 Centralized and Comprehensive Log Aggregation", "SubSection": "", - "SubSectionObjective": "Ensure all operational and security logs from across the cloud environment, including\napplications, operating systems, network traffic, and cloud service activity, are captured\nautomatically and streamed to a central, secure log management service.", + "SubSectionObjective": "Ensure all operational and security logs from across the cloud environment, including applications, operating systems, network traffic, and cloud service activity, are captured automatically and streamed to a central, secure log management service.", "Applicability": [ "tlp-clear", "tlp-green", @@ -2367,15 +1648,15 @@ ] }, { - "Id": "CCC.Logging.C02.TR01", - "Description": "When a new log bucket or stream is created, its retention policy MUST be configured\nin accordance with organisation's data retention policy.", + "Id": "CCC.Logging.CN02.AR01", + "Description": "When a new log bucket or stream is created, its retention policy MUST be configured in accordance with organisation's data retention policy.", "Attributes": [ { "FamilyName": "Data", - "FamilyDescription": "Controls related to the confidentiality, integrity and availability of log data.\n", - "Section": "CCC.Logging.C02 Enforce Data Retention Policy for Logs", + "FamilyDescription": "Controls related to the confidentiality, integrity and availability of log data. ", + "Section": "CCC.Logging.CN02 Enforce Data Retention Policy for Logs", "SubSection": "", - "SubSectionObjective": "Ensure that the retention period configured for logs aligns with the organization's\ndata retention policy.", + "SubSectionObjective": "Ensure that the retention period configured for logs aligns with the organization's data retention policy.", "Applicability": [ "tlp-clear", "tlp-green", @@ -2412,15 +1693,15 @@ ] }, { - "Id": "CCC.Logging.C02.TR02", - "Description": "When a query is performed to retrieve log events older than the number of days defined\nin the organisation's data retention policy, it MUST return an empty result.", + "Id": "CCC.Logging.CN02.AR02", + "Description": "When a query is performed to retrieve log events older than the number of days defined in the organisation's data retention policy, it MUST return an empty result.", "Attributes": [ { "FamilyName": "Data", - "FamilyDescription": "Controls related to the confidentiality, integrity and availability of log data.\n", - "Section": "CCC.Logging.C02 Enforce Data Retention Policy for Logs", + "FamilyDescription": "Controls related to the confidentiality, integrity and availability of log data. ", + "Section": "CCC.Logging.CN02 Enforce Data Retention Policy for Logs", "SubSection": "", - "SubSectionObjective": "Ensure that the retention period configured for logs aligns with the organization's\ndata retention policy.", + "SubSectionObjective": "Ensure that the retention period configured for logs aligns with the organization's data retention policy.", "Applicability": [ "tlp-clear", "tlp-green", @@ -2459,20 +1740,20 @@ ] }, { - "Id": "CCC.AuditLog.C08.TR01", - "Description": "When an attempt is made to modify or delete data before the object\nlock period expires, then the action MUST be denied.", + "Id": "CCC.AuditLog.CN08.AR01", + "Description": "When an attempt is made to modify or delete data before the object lock period expires, then the action MUST be denied.", "Attributes": [ { "FamilyName": "Data", - "FamilyDescription": "Controls related to the confidentiality, integrity and availability of log data.\n", - "Section": "CCC.Logging.C03 Enable Object Lock On Log Bucket", + "FamilyDescription": "Controls related to the confidentiality, integrity and availability of log data. ", + "Section": "CCC.Logging.CN03 Enable Object Lock On Log Bucket", "SubSection": "", - "SubSectionObjective": "Ensure log immutability by enabling Write Once, Read Many (WORM) protection\nusing object lock on log storage buckets. This prevents logs from being modified\nor deleted during the defined retention period, supporting compliance and forensic\nintegrity.", + "SubSectionObjective": "Ensure log immutability by enabling Write Once, Read Many (WORM) protection using object lock on log storage buckets. This prevents logs from being modified or deleted during the defined retention period, supporting compliance and forensic integrity.", "Applicability": [ "tlp-red", "tlp-amber" ], - "Recommendation": "Configure object lock policy.\n", + "Recommendation": "Configure object lock policy. ", "SectionThreatMappings": [ { "ReferenceId": "CCC", @@ -2501,20 +1782,20 @@ "Checks": [] }, { - "Id": "CCC.AuditLog.C04.TR01", + "Id": "CCC.AuditLog.CN04.AR01", "Description": "When restricted fields are accessed by unauthorized users, then those fields MUST remain masked.", "Attributes": [ { "FamilyName": "Identity and Access Management", - "FamilyDescription": "Controls that restrict who can access and modify logs.\n", - "Section": "CCC.Logging.C04 Restrict Field And Log Type Access", + "FamilyDescription": "Controls that restrict who can access and modify logs. ", + "Section": "CCC.Logging.CN04 Restrict Field And Log Type Access", "SubSection": "", - "SubSectionObjective": "Configure access to logs to follow the principle of least privilege in particular where technically\npossible limit the log fields users have access to to prevent accidental exposure to sensitive\ninformation such as PII.", + "SubSectionObjective": "Configure access to logs to follow the principle of least privilege in particular where technically possible limit the log fields users have access to to prevent accidental exposure to sensitive information such as PII.", "Applicability": [ "tlp-red", "tlp-amber" ], - "Recommendation": "Review field level access controls on log data.\n", + "Recommendation": "Review field level access controls on log data. ", "SectionThreatMappings": [ { "ReferenceId": "CCC", @@ -2552,21 +1833,21 @@ ] }, { - "Id": "CCC.Logging.C05.TR01", - "Description": "When a log storage bucket is created, the bucket's access control settings MUST\nexplicitly deny public read and write access.", + "Id": "CCC.Logging.CN05.AR01", + "Description": "When a log storage bucket is created, the bucket's access control settings MUST explicitly deny public read and write access.", "Attributes": [ { "FamilyName": "Identity and Access Management", - "FamilyDescription": "Controls that restrict who can access and modify logs.\n", - "Section": "CCC.Logging.C05 Ensure Log Bucket is Not Publicly Accessible", + "FamilyDescription": "Controls that restrict who can access and modify logs. ", + "Section": "CCC.Logging.CN05 Ensure Log Bucket is Not Publicly Accessible", "SubSection": "", - "SubSectionObjective": "Ensure that log storage buckets are not publicly accessible to prevent unauthorized\naccess to sensitive log data. In addition, logs should be replicated to another cloud\nregion to enhance availability, durability, and support disaster recovery requirements.", + "SubSectionObjective": "Ensure that log storage buckets are not publicly accessible to prevent unauthorized access to sensitive log data. In addition, logs should be replicated to another cloud region to enhance availability, durability, and support disaster recovery requirements.", "Applicability": [ "tlp-red", "tlp-amber", "tlp-green" ], - "Recommendation": "Configure bucket policies and access control lists (ACLs) to restrict public access.\nRegularly review bucket permissions to ensure no public access has been inadvertently granted.\n", + "Recommendation": "Configure bucket policies and access control lists (ACLs) to restrict public access. Regularly review bucket permissions to ensure no public access has been inadvertently granted. ", "SectionThreatMappings": [ { "ReferenceId": "CCC", @@ -2600,21 +1881,21 @@ ] }, { - "Id": "CCC.Logging.C05.TR02", - "Description": "When the URL of a log storage bucket's object is accessed publicly, the action MUST be denied\nby bucket policy.", + "Id": "CCC.Logging.CN05.AR02", + "Description": "When the URL of a log storage bucket's object is accessed publicly, the action MUST be denied by bucket policy.", "Attributes": [ { "FamilyName": "Identity and Access Management", - "FamilyDescription": "Controls that restrict who can access and modify logs.\n", - "Section": "CCC.Logging.C05 Ensure Log Bucket is Not Publicly Accessible", + "FamilyDescription": "Controls that restrict who can access and modify logs. ", + "Section": "CCC.Logging.CN05 Ensure Log Bucket is Not Publicly Accessible", "SubSection": "", - "SubSectionObjective": "Ensure that log storage buckets are not publicly accessible to prevent unauthorized\naccess to sensitive log data. In addition, logs should be replicated to another cloud\nregion to enhance availability, durability, and support disaster recovery requirements.", + "SubSectionObjective": "Ensure that log storage buckets are not publicly accessible to prevent unauthorized access to sensitive log data. In addition, logs should be replicated to another cloud region to enhance availability, durability, and support disaster recovery requirements.", "Applicability": [ "tlp-red", "tlp-amber", "tlp-green" ], - "Recommendation": "Configure bucket policies and access control lists (ACLs) to restrict public access.\nRegularly review bucket permissions to ensure no public access has been inadvertently granted.\n", + "Recommendation": "Configure bucket policies and access control lists (ACLs) to restrict public access. Regularly review bucket permissions to ensure no public access has been inadvertently granted. ", "SectionThreatMappings": [ { "ReferenceId": "CCC", @@ -2649,15 +1930,15 @@ ] }, { - "Id": "CCC.Logging.C06.TR01", - "Description": "When a single principal executes an anomalously high number of log queries,\nan alert MUST be generated.", + "Id": "CCC.Logging.CN06.AR01", + "Description": "When a single principal executes an anomalously high number of log queries, an alert MUST be generated.", "Attributes": [ { "FamilyName": "Logging and Monitoring", - "FamilyDescription": "Controls that collect, alert, and retain logging-related events.\n", - "Section": "CCC.Logging.C06 Detect and Alert on Potential Log Exfiltration", + "FamilyDescription": "Controls that collect, alert, and retain logging-related events. ", + "Section": "CCC.Logging.CN06 Detect and Alert on Potential Log Exfiltration", "SubSection": "", - "SubSectionObjective": "Identify and alert on anomalous data access patterns that may indicate an attempt\nto exfiltrate log data.", + "SubSectionObjective": "Identify and alert on anomalous data access patterns that may indicate an attempt to exfiltrate log data.", "Applicability": [ "tlp-green", "tlp-amber", @@ -2696,15 +1977,15 @@ ] }, { - "Id": "CCC.Logging.C07.TR01", - "Description": "When an audit log event is recorded that corresponds to a modification of the logging service\nconfiguration such as disabling a log trail, deleting a log sink, or altering a log forwarding rule,\nan alert MUST be generated.", + "Id": "CCC.Logging.CN07.AR01", + "Description": "When an audit log event is recorded that corresponds to a modification of the logging service configuration such as disabling a log trail, deleting a log sink, or altering a log forwarding rule, an alert MUST be generated.", "Attributes": [ { "FamilyName": "Logging and Monitoring", - "FamilyDescription": "Controls that collect, alert, and retain logging-related events.\n", - "Section": "CCC.Logging.C07 Detect and Alert on Log Service Tampering", + "FamilyDescription": "Controls that collect, alert, and retain logging-related events. ", + "Section": "CCC.Logging.CN07 Detect and Alert on Log Service Tampering", "SubSection": "", - "SubSectionObjective": "Alert when any component of the critical logging infrastructure is disabled, modified,\nor deleted, indicating a defense evasion attempt.", + "SubSectionObjective": "Alert when any component of the critical logging infrastructure is disabled, modified, or deleted, indicating a defense evasion attempt.", "Applicability": [ "tlp-clear", "tlp-green", @@ -2755,13 +2036,13 @@ ] }, { - "Id": "CCC.ObjStor.C01.TR01", + "Id": "CCC.ObjStor.CN01.AR01", "Description": "When a request is made to read a protected bucket, the service MUST prevent any request using KMS keys not listed as trusted by the organization.", "Attributes": [ { "FamilyName": "Data", "FamilyDescription": "TODO: Describe this control family", - "Section": "CCC.C01 Prevent Unencrypted Requests", + "Section": "CCC.CN01 Prevent Unencrypted Requests", "SubSection": "CCC.ObjStor.C01 Prevent Requests to Buckets or Objects with Untrusted KMS Keys", "SubSectionObjective": "Prevent any requests to object storage buckets or objects using untrusted KMS keys to protect against unauthorized data encryption that can impact data availability and integrity.", "Applicability": [ @@ -2815,13 +2096,13 @@ ] }, { - "Id": "CCC.ObjStor.C01.TR02", + "Id": "CCC.ObjStor.CN01.AR02", "Description": "When a request is made to read a protected object, the service MUST prevent any request using KMS keys not listed as trusted by the organization.", "Attributes": [ { "FamilyName": "Data", "FamilyDescription": "TODO: Describe this control family", - "Section": "CCC.C01 Prevent Unencrypted Requests", + "Section": "CCC.CN01 Prevent Unencrypted Requests", "SubSection": "CCC.ObjStor.C01 Prevent Requests to Buckets or Objects with Untrusted KMS Keys", "SubSectionObjective": "Prevent any requests to object storage buckets or objects using untrusted KMS keys to protect against unauthorized data encryption that can impact data availability and integrity.", "Applicability": [ @@ -2877,13 +2158,13 @@ ] }, { - "Id": "CCC.ObjStor.C01.TR03", + "Id": "CCC.ObjStor.CN01.AR03", "Description": "When a request is made to write to a bucket, the service MUST prevent any request using KMS keys not listed as trusted by the organization.", "Attributes": [ { "FamilyName": "Data", "FamilyDescription": "TODO: Describe this control family", - "Section": "CCC.C01 Prevent Unencrypted Requests", + "Section": "CCC.CN01 Prevent Unencrypted Requests", "SubSection": "CCC.ObjStor.C01 Prevent Requests to Buckets or Objects with Untrusted KMS Keys", "SubSectionObjective": "Prevent any requests to object storage buckets or objects using untrusted KMS keys to protect against unauthorized data encryption that can impact data availability and integrity.", "Applicability": [ @@ -2940,13 +2221,13 @@ ] }, { - "Id": "CCC.ObjStor.C01.TR04", + "Id": "CCC.ObjStor.CN01.AR04", "Description": "When a request is made to write to an object, the service MUST prevent any request using KMS keys not listed as trusted by the organization.", "Attributes": [ { "FamilyName": "Data", "FamilyDescription": "TODO: Describe this control family", - "Section": "CCC.C01 Prevent Unencrypted Requests", + "Section": "CCC.CN01 Prevent Unencrypted Requests", "SubSection": "CCC.ObjStor.C01 Prevent Requests to Buckets or Objects with Untrusted KMS Keys", "SubSectionObjective": "Prevent any requests to object storage buckets or objects using untrusted KMS keys to protect against unauthorized data encryption that can impact data availability and integrity.", "Applicability": [ @@ -3001,13 +2282,13 @@ ] }, { - "Id": "CCC.ObjStor.C03.TR01", + "Id": "CCC.ObjStor.CN03.AR01", "Description": "When an object storage bucket deletion is attempted, the bucket MUST be fully recoverable for a set time-frame after deletion is requested.", "Attributes": [ { "FamilyName": "Data", "FamilyDescription": "TODO: Describe this control family", - "Section": "CCC.C03 Implement Multi-factor Authentication (MFA) for Access", + "Section": "CCC.CN03 Implement Multi-factor Authentication (MFA) for Access", "SubSection": "CCC.ObjStor.C03 Prevent Bucket Deletion Through Irrevocable Bucket Retention Policy", "SubSectionObjective": "Ensure that object storage bucket is not deleted after creation, and that the preventative measure cannot be unset.", "Applicability": [ @@ -3060,13 +2341,13 @@ ] }, { - "Id": "CCC.ObjStor.C03.TR02", + "Id": "CCC.ObjStor.CN03.AR02", "Description": "When an attempt is made to modify the retention policy for an object storage bucket, the service MUST prevent the policy from being modified.", "Attributes": [ { "FamilyName": "Data", "FamilyDescription": "TODO: Describe this control family", - "Section": "CCC.C03 Implement Multi-factor Authentication (MFA) for Access", + "Section": "CCC.CN03 Implement Multi-factor Authentication (MFA) for Access", "SubSection": "CCC.ObjStor.C03 Prevent Bucket Deletion Through Irrevocable Bucket Retention Policy", "SubSectionObjective": "Ensure that object storage bucket is not deleted after creation, and that the preventative measure cannot be unset.", "Applicability": [ @@ -3116,13 +2397,13 @@ "Checks": [] }, { - "Id": "CCC.ObjStor.C04.TR01", + "Id": "CCC.ObjStor.CN04.AR01", "Description": "When an object is uploaded to the object storage system, the object MUST automatically receive a default retention policy that prevents premature deletion or modification.", "Attributes": [ { "FamilyName": "Data", "FamilyDescription": "TODO: Describe this control family", - "Section": "CCC.C04 Log All Access and Changes", + "Section": "CCC.CN04 Log All Access and Changes", "SubSection": "CCC.ObjStor.C04 Objects have an Effective Retention Policy by Default", "SubSectionObjective": "Ensure that all objects stored in the object storage system have a retention policy applied by default, preventing premature deletion or modification of objects and ensuring compliance with data retention regulations.", "Applicability": [ @@ -3176,13 +2457,13 @@ ] }, { - "Id": "CCC.ObjStor.C04.TR02", + "Id": "CCC.ObjStor.CN04.AR02", "Description": "When an attempt is made to delete or modify an object that is subject to an active retention policy, the service MUST prevent the action from being completed.", "Attributes": [ { "FamilyName": "Data", "FamilyDescription": "TODO: Describe this control family", - "Section": "CCC.C04 Log All Access and Changes", + "Section": "CCC.CN04 Log All Access and Changes", "SubSection": "CCC.ObjStor.C04 Objects have an Effective Retention Policy by Default", "SubSectionObjective": "Ensure that all objects stored in the object storage system have a retention policy applied by default, preventing premature deletion or modification of objects and ensuring compliance with data retention regulations.", "Applicability": [ @@ -3235,13 +2516,13 @@ ] }, { - "Id": "CCC.ObjStor.C05.TR01", + "Id": "CCC.ObjStor.CN05.AR01", "Description": "When an object is uploaded to the object storage bucket, the object MUST be stored with a unique identifier.", "Attributes": [ { "FamilyName": "Data", "FamilyDescription": "TODO: Describe this control family", - "Section": "CCC.C05 Prevent Access from Untrusted Entities", + "Section": "CCC.CN05 Prevent Access from Untrusted Entities", "SubSection": "CCC.ObjStor.C05 Versioning is Enabled for All Objects in the Bucket", "SubSectionObjective": "Ensure that versioning is enabled for all objects stored in the object storage bucket to enable recovery of previous versions of objects in case of loss or corruption.", "Applicability": [ @@ -3293,13 +2574,13 @@ ] }, { - "Id": "CCC.ObjStor.C05.TR02", + "Id": "CCC.ObjStor.CN05.AR02", "Description": "When an object is modified, the service MUST assign a new unique identifier to the modified object to differentiate it from the previous version.", "Attributes": [ { "FamilyName": "Data", "FamilyDescription": "TODO: Describe this control family", - "Section": "CCC.C05 Prevent Access from Untrusted Entities", + "Section": "CCC.CN05 Prevent Access from Untrusted Entities", "SubSection": "CCC.ObjStor.C05 Versioning is Enabled for All Objects in the Bucket", "SubSectionObjective": "Ensure that versioning is enabled for all objects stored in the object storage bucket to enable recovery of previous versions of objects in case of loss or corruption.", "Applicability": [ @@ -3351,13 +2632,13 @@ ] }, { - "Id": "CCC.ObjStor.C05.TR03", + "Id": "CCC.ObjStor.CN05.AR03", "Description": "When an object is modified, the service MUST allow for recovery of previous versions of the object.", "Attributes": [ { "FamilyName": "Data", "FamilyDescription": "TODO: Describe this control family", - "Section": "CCC.C05 Prevent Access from Untrusted Entities", + "Section": "CCC.CN05 Prevent Access from Untrusted Entities", "SubSection": "CCC.ObjStor.C05 Versioning is Enabled for All Objects in the Bucket", "SubSectionObjective": "Ensure that versioning is enabled for all objects stored in the object storage bucket to enable recovery of previous versions of objects in case of loss or corruption.", "Applicability": [ @@ -3409,13 +2690,13 @@ ] }, { - "Id": "CCC.ObjStor.C05.TR04", + "Id": "CCC.ObjStor.CN05.AR04", "Description": "When an object is deleted, the service MUST retain other versions of the object to allow for recovery of previous versions.", "Attributes": [ { "FamilyName": "Data", "FamilyDescription": "TODO: Describe this control family", - "Section": "CCC.C05 Prevent Access from Untrusted Entities", + "Section": "CCC.CN05 Prevent Access from Untrusted Entities", "SubSection": "CCC.ObjStor.C05 Versioning is Enabled for All Objects in the Bucket", "SubSectionObjective": "Ensure that versioning is enabled for all objects stored in the object storage bucket to enable recovery of previous versions of objects in case of loss or corruption.", "Applicability": [ @@ -3467,13 +2748,13 @@ ] }, { - "Id": "CCC.ObjStor.C06.TR01", + "Id": "CCC.ObjStor.CN06.AR01", "Description": "When an object storage bucket is accessed, the service MUST store access logs in a separate data store.", "Attributes": [ { "FamilyName": "Data", "FamilyDescription": "TODO: Describe this control family", - "Section": "CCC.C06 Prevent Deployment in Restricted Regions", + "Section": "CCC.CN06 Prevent Deployment in Restricted Regions", "SubSection": "CCC.ObjStor.C06 Access Logs are Stored in a Separate Data Store", "SubSectionObjective": "Ensure that access logs for object storage buckets are stored in a separate data store to protect against unauthorized access, tampering, or deletion of logs (Logbuckets are exempt from this requirement, but must be tlp-red).", "Applicability": [ @@ -3528,13 +2809,13 @@ ] }, { - "Id": "CCC.ObjStor.C02.TR01", + "Id": "CCC.ObjStor.CN02.AR01", "Description": "When a permission set is allowed for an object in a bucket, the service MUST allow the same permission set to access all objects in the same bucket.", "Attributes": [ { "FamilyName": "Identity and Access Management", "FamilyDescription": "TODO: Describe this control family", - "Section": "CCC.C02 Ensure Data Encryption at Rest for All Stored Data", + "Section": "CCC.CN02 Ensure Data Encryption at Rest for All Stored Data", "SubSection": "CCC.ObjStor.C02 Enforce Uniform Bucket-level Access to Prevent Inconsistent Permissions", "SubSectionObjective": "Ensure that uniform bucket-level access is enforced across all object storage buckets. This prevents the use of ad-hoc or inconsistent object-level permissions, ensuring centralized, consistent, and secure access management in accordance with the principle of least privilege.", "Applicability": [ @@ -3588,13 +2869,13 @@ ] }, { - "Id": "CCC.ObjStor.C02.TR02", + "Id": "CCC.ObjStor.CN02.AR02", "Description": "When a permission set is denied for an object in a bucket, the service MUST deny the same permission set to access all objects in the same bucket.", "Attributes": [ { "FamilyName": "Identity and Access Management", "FamilyDescription": "TODO: Describe this control family", - "Section": "CCC.C02 Ensure Data Encryption at Rest for All Stored Data", + "Section": "CCC.CN02 Ensure Data Encryption at Rest for All Stored Data", "SubSection": "CCC.ObjStor.C02 Enforce Uniform Bucket-level Access to Prevent Inconsistent Permissions", "SubSectionObjective": "Ensure that uniform bucket-level access is enforced across all object storage buckets. This prevents the use of ad-hoc or inconsistent object-level permissions, ensuring centralized, consistent, and secure access management in accordance with the principle of least privilege.", "Applicability": [ @@ -3648,1001 +2929,9 @@ "storage_ensure_private_endpoints_in_storage_accounts" ] }, - { - "Id": "CCC.MLDE.CN01.AR01", - "Description": "Verify that only authorized users can access MLDE resources,\nand that access modes are properly defined and enforced.", - "Attributes": [ - { - "FamilyName": "Identity and Access Management", - "FamilyDescription": "TODO: Describe this control family", - "Section": "CCC.MLDE.CN01 Define Access Mode for ML Development Environments", - "SubSection": "", - "SubSectionObjective": "Ensure that access to Machine Learning Development Environment (MLDE)\nresources is strictly defined and controlled.\nOnly authorized users with appropriate permissions can access these environments,\nmitigating the risk of unauthorized access, data leakage, or service disruption.", - "Applicability": [ - "tlp-red", - "tlp-amber", - "tlp-green", - "tlp-clear" - ], - "Recommendation": "", - "SectionThreatMappings": [ - { - "ReferenceId": "CCC", - "Identifiers": [ - "CCC.MLDE.TH01", - "CCC.TH01" - ] - } - ], - "SectionGuidelineMappings": [ - { - "ReferenceId": "NIST-CSF", - "Identifiers": [ - "PR.AC-3" - ] - }, - { - "ReferenceId": "ISO_27001", - "Identifiers": [ - "2013 A.9.1.1", - "2013 A.9.2.1" - ] - }, - { - "ReferenceId": "NIST_800_53", - "Identifiers": [ - "AC-2", - "AC-3" - ] - }, - { - "ReferenceId": "CCM", - "Identifiers": [ - "IAM-01", - "IAM-02" - ] - } - ] - } - ], - "Checks": [ - "aks_cluster_rbac_enabled", - "aks_clusters_public_access_disabled", - "aks_network_policy_enabled", - "app_ensure_auth_is_set_up", - "app_register_with_identity", - "app_function_identity_is_configured", - "app_function_identity_without_admin_privileges", - "app_function_not_publicly_accessible", - "app_function_access_keys_configured", - "keyvault_rbac_enabled", - "keyvault_private_endpoints", - "keyvault_access_only_through_private_endpoints", - "iam_custom_role_has_permissions_to_administer_resource_locks", - "iam_role_user_access_admin_restricted", - "iam_subscription_roles_owner_custom_not_created", - "entra_policy_user_consent_for_verified_apps", - "entra_security_defaults_enabled", - "entra_trusted_named_locations_exists", - "entra_global_admin_in_less_than_five_users", - "entra_non_privileged_user_has_mfa", - "entra_privileged_user_has_mfa", - "entra_policy_default_users_cannot_create_security_groups", - "entra_policy_ensure_default_user_cannot_create_apps", - "entra_users_cannot_create_microsoft_365_groups" - ] - }, - { - "Id": "CCC.MLDE.CN03.AR01", - "Description": "Verify that root access is disabled on MLDE instances containing sensitive data.", - "Attributes": [ - { - "FamilyName": "Identity and Access Management", - "FamilyDescription": "TODO: Describe this control family", - "Section": "CCC.MLDE.CN03 Disable Root Access on MLDE Instances", - "SubSection": "", - "SubSectionObjective": "Prevent users from obtaining root access on MLDE instances to reduce the\nrisk of unauthorized system modifications and potential security breaches.", - "Applicability": [ - "tlp-red" - ], - "Recommendation": "", - "SectionThreatMappings": [ - { - "ReferenceId": "CCC", - "Identifiers": [ - "CCC.MLDE.TH01" - ] - } - ], - "SectionGuidelineMappings": [ - { - "ReferenceId": "NIST-CSF", - "Identifiers": [ - "PR.AC-4" - ] - }, - { - "ReferenceId": "NIST_800_53", - "Identifiers": [ - "AC-6" - ] - }, - { - "ReferenceId": "CCM", - "Identifiers": [ - "IAM-08", - "IAM-12" - ] - }, - { - "ReferenceId": "ISO_27001", - "Identifiers": [ - "2013 A.9.2.3" - ] - } - ] - } - ], - "Checks": [ - "aks_clusters_created_with_private_nodes", - "aks_clusters_public_access_disabled", - "aks_network_policy_enabled", - "app_function_not_publicly_accessible", - "app_function_identity_without_admin_privileges", - "iam_role_user_access_admin_restricted", - "vm_jit_access_enabled", - "vm_linux_enforce_ssh_authentication", - "app_function_identity_is_configured" - ] - }, - { - "Id": "CCC.MLDE.CN03.AR02", - "Description": "For MLDE instances without sensitive data, ensure that root access is only\nenabled when necessary and properly authorized.", - "Attributes": [ - { - "FamilyName": "Identity and Access Management", - "FamilyDescription": "TODO: Describe this control family", - "Section": "CCC.MLDE.CN03 Disable Root Access on MLDE Instances", - "SubSection": "", - "SubSectionObjective": "Prevent users from obtaining root access on MLDE instances to reduce the\nrisk of unauthorized system modifications and potential security breaches.", - "Applicability": [ - "tlp-red", - "tlp-amber", - "tlp-green", - "tlp-clear" - ], - "Recommendation": "", - "SectionThreatMappings": [ - { - "ReferenceId": "CCC", - "Identifiers": [ - "CCC.MLDE.TH01" - ] - } - ], - "SectionGuidelineMappings": [ - { - "ReferenceId": "NIST-CSF", - "Identifiers": [ - "PR.AC-4" - ] - }, - { - "ReferenceId": "NIST_800_53", - "Identifiers": [ - "AC-6" - ] - }, - { - "ReferenceId": "CCM", - "Identifiers": [ - "IAM-08", - "IAM-12" - ] - }, - { - "ReferenceId": "ISO_27001", - "Identifiers": [ - "2013 A.9.2.3" - ] - } - ] - } - ], - "Checks": [ - "vm_jit_access_enabled", - "vm_linux_enforce_ssh_authentication", - "app_function_identity_without_admin_privileges", - "app_function_identity_is_configured", - "iam_role_user_access_admin_restricted", - "iam_subscription_roles_owner_custom_not_created", - "entra_global_admin_in_less_than_five_users", - "entra_privileged_user_has_mfa", - "entra_conditional_access_policy_require_mfa_for_management_api" - ] - }, - { - "Id": "CCC.MLDE.CN04.AR01", - "Description": "Verify that terminal access is disabled on MLDE instances containing sensitive data.", - "Attributes": [ - { - "FamilyName": "Identity and Access Management", - "FamilyDescription": "TODO: Describe this control family", - "Section": "CCC.MLDE.CN04 Disable Terminal Access on MLDE Instances", - "SubSection": "", - "SubSectionObjective": "Prevent users from accessing the terminal on MLDE instances to limit the risk of\nunauthorized commands and potential system compromise.", - "Applicability": [ - "tlp-red" - ], - "Recommendation": "", - "SectionThreatMappings": [ - { - "ReferenceId": "CCC", - "Identifiers": [ - "CCC.MLDE.TH01" - ] - } - ], - "SectionGuidelineMappings": [ - { - "ReferenceId": "NIST-CSF", - "Identifiers": [ - "PR.AC-4" - ] - }, - { - "ReferenceId": "NIST_800_53", - "Identifiers": [ - "AC-6" - ] - }, - { - "ReferenceId": "CCM", - "Identifiers": [ - "IAM-08" - ] - }, - { - "ReferenceId": "ISO_27001", - "Identifiers": [ - "2013 A.9.2.3" - ] - } - ] - } - ], - "Checks": [ - "vm_jit_access_enabled", - "vm_linux_enforce_ssh_authentication" - ] - }, - { - "Id": "CCC.MLDE.CN04.AR02", - "Description": "For MLDE instances without sensitive data, ensure that terminal access is only\nenabled when necessary and properly authorized.", - "Attributes": [ - { - "FamilyName": "Identity and Access Management", - "FamilyDescription": "TODO: Describe this control family", - "Section": "CCC.MLDE.CN04 Disable Terminal Access on MLDE Instances", - "SubSection": "", - "SubSectionObjective": "Prevent users from accessing the terminal on MLDE instances to limit the risk of\nunauthorized commands and potential system compromise.", - "Applicability": [ - "tlp-red", - "tlp-amber", - "tlp-green", - "tlp-clear" - ], - "Recommendation": "", - "SectionThreatMappings": [ - { - "ReferenceId": "CCC", - "Identifiers": [ - "CCC.MLDE.TH01" - ] - } - ], - "SectionGuidelineMappings": [ - { - "ReferenceId": "NIST-CSF", - "Identifiers": [ - "PR.AC-4" - ] - }, - { - "ReferenceId": "NIST_800_53", - "Identifiers": [ - "AC-6" - ] - }, - { - "ReferenceId": "CCM", - "Identifiers": [ - "IAM-08" - ] - }, - { - "ReferenceId": "ISO_27001", - "Identifiers": [ - "2013 A.9.2.3" - ] - } - ] - } - ], - "Checks": [ - "vm_jit_access_enabled", - "vm_linux_enforce_ssh_authentication" - ] - }, - { - "Id": "CCC.MLDE.CN02.AR01", - "Description": "Confirm that file download functionality is disabled on MLDE instances containing sensitive data.", - "Attributes": [ - { - "FamilyName": "Data Protection", - "FamilyDescription": "TODO: Describe this control family", - "Section": "CCC.MLDE.CN02 Disable File Downloads on MLDE Instances", - "SubSection": "", - "SubSectionObjective": "Prevent unauthorized file downloads from MLDE instances to protect sensitive data from being exfiltrated.", - "Applicability": [ - "tlp-red" - ], - "Recommendation": "", - "SectionThreatMappings": [ - { - "ReferenceId": "CCC", - "Identifiers": [ - "CCC.MLDE.TH02", - "CCC.TH02" - ] - } - ], - "SectionGuidelineMappings": [ - { - "ReferenceId": "NIST-CSF", - "Identifiers": [ - "PR.DS-5" - ] - }, - { - "ReferenceId": "CCM", - "Identifiers": [ - "DSI-05", - "DSI-07" - ] - }, - { - "ReferenceId": "ISO_27001", - "Identifiers": [ - "2013 A.13.2.1" - ] - }, - { - "ReferenceId": "NIST_800_53", - "Identifiers": [ - "SC-7", - "SC-8" - ] - } - ] - } - ], - "Checks": [] - }, - { - "Id": "CCC.MLDE.CN02.AR02", - "Description": "For MLDE instances without sensitive data, ensure that file downloads are monitored and logged.", - "Attributes": [ - { - "FamilyName": "Data Protection", - "FamilyDescription": "TODO: Describe this control family", - "Section": "", - "SubSection": "CCC.MLDE.CN02 Disable File Downloads on MLDE Instances", - "SubSectionObjective": "Prevent unauthorized file downloads from MLDE instances to protect sensitive data from being exfiltrated.", - "Applicability": [ - "tlp-red", - "tlp-amber", - "tlp-green", - "tlp-clear" - ], - "Recommendation": "", - "SectionThreatMappings": [ - { - "ReferenceId": "CCC", - "Identifiers": [ - "CCC.MLDE.TH02", - "CCC.TH02" - ] - } - ], - "SectionGuidelineMappings": [ - { - "ReferenceId": "NIST-CSF", - "Identifiers": [ - "PR.DS-5" - ] - }, - { - "ReferenceId": "CCM", - "Identifiers": [ - "DSI-05", - "DSI-07" - ] - }, - { - "ReferenceId": "ISO_27001", - "Identifiers": [ - "2013 A.13.2.1" - ] - }, - { - "ReferenceId": "NIST_800_53", - "Identifiers": [ - "SC-7", - "SC-8" - ] - } - ] - } - ], - "Checks": [ - "monitor_diagnostic_settings_exists", - "monitor_diagnostic_setting_with_appropriate_categories" - ] - }, - { - "Id": "CCC.MLDE.CN05.AR01", - "Description": "Verify that only approved VM and container images can be selected when creating MLDE instances.", - "Attributes": [ - { - "FamilyName": "Configuration Management", - "FamilyDescription": "TODO: Describe this control family", - "Section": "", - "SubSection": "CCC.MLDE.CN05 Restrict Environment Options on MLDE Instances", - "SubSectionObjective": "Limit the virtual machine and container image options available when creating\nnew MLDE instances to approved and secure configurations.", - "Applicability": [ - "tlp-red", - "tlp-amber" - ], - "Recommendation": "", - "SectionThreatMappings": [ - { - "ReferenceId": "CCC", - "Identifiers": [ - "CCC.MLDE.TH04" - ] - } - ], - "SectionGuidelineMappings": [ - { - "ReferenceId": "NIST-CSF", - "Identifiers": [ - "PR.IP-1" - ] - }, - { - "ReferenceId": "CCM", - "Identifiers": [ - "TVM-02" - ] - }, - { - "ReferenceId": "ISO_27001", - "Identifiers": [ - "2013 A.12.5.1" - ] - }, - { - "ReferenceId": "NIST_800_53", - "Identifiers": [ - "CM-2" - ] - } - ] - } - ], - "Checks": [ - "vm_ensure_using_approved_images", - "vm_desired_sku_size", - "containerregistry_not_publicly_accessible", - "containerregistry_uses_private_link" - ] - }, - { - "Id": "CCC.MLDE.CN05.AR02", - "Description": "Attempt to create an MLDE instance with an unapproved image and confirm that it is denied.", - "Attributes": [ - { - "FamilyName": "Configuration Management", - "FamilyDescription": "TODO: Describe this control family", - "Section": "", - "SubSection": "CCC.MLDE.CN05 Restrict Environment Options on MLDE Instances", - "SubSectionObjective": "Limit the virtual machine and container image options available when creating\nnew MLDE instances to approved and secure configurations.", - "Applicability": [ - "tlp-red" - ], - "Recommendation": "", - "SectionThreatMappings": [ - { - "ReferenceId": "CCC", - "Identifiers": [ - "CCC.MLDE.TH04" - ] - } - ], - "SectionGuidelineMappings": [ - { - "ReferenceId": "NIST-CSF", - "Identifiers": [ - "PR.IP-1" - ] - }, - { - "ReferenceId": "CCM", - "Identifiers": [ - "TVM-02" - ] - }, - { - "ReferenceId": "ISO_27001", - "Identifiers": [ - "2013 A.12.5.1" - ] - }, - { - "ReferenceId": "NIST_800_53", - "Identifiers": [ - "CM-2" - ] - } - ] - } - ], - "Checks": [ - "vm_ensure_using_approved_images" - ] - }, - { - "Id": "CCC.MLDE.CN06.AR01", - "Description": "Verify that automatic scheduled upgrades are enabled on user-managed\nMLDE instances containing sensitive data.", - "Attributes": [ - { - "FamilyName": "Vulnerability Management", - "FamilyDescription": "TODO: Describe this control family", - "Section": "", - "SubSection": "CCC.MLDE.CN06 Require Automatic Scheduled Upgrades on User-Managed MLDE Instances", - "SubSectionObjective": "Ensure that MLDE instances are kept up-to-date with the\nlatest security patches by enforcing automatic scheduled upgrades.", - "Applicability": [ - "tlp-red" - ], - "Recommendation": "", - "SectionThreatMappings": [ - { - "ReferenceId": "CCC", - "Identifiers": [ - "CCC.MLDE.TH04", - "CCC.TH06" - ] - } - ], - "SectionGuidelineMappings": [ - { - "ReferenceId": "NIST-CSF", - "Identifiers": [ - "PR.IP-12" - ] - }, - { - "ReferenceId": "CCM", - "Identifiers": [ - "TVM-01", - "TVM-02" - ] - }, - { - "ReferenceId": "ISO_27001", - "Identifiers": [ - "2013 A.12.6.1" - ] - }, - { - "ReferenceId": "NIST_800_53", - "Identifiers": [ - "SI-2" - ] - } - ] - } - ], - "Checks": [ - "defender_ensure_system_updates_are_applied" - ] - }, - { - "Id": "CCC.MLDE.CN06.AR02", - "Description": "Ensure that the upgrade schedule is appropriately configured and\ndoes not interfere with critical operations.", - "Attributes": [ - { - "FamilyName": "Vulnerability Management", - "FamilyDescription": "TODO: Describe this control family", - "Section": "", - "SubSection": "CCC.MLDE.CN06 Require Automatic Scheduled Upgrades on User-Managed MLDE Instances", - "SubSectionObjective": "Ensure that MLDE instances are kept up-to-date with the\nlatest security patches by enforcing automatic scheduled upgrades.", - "Applicability": [ - "tlp-red", - "tlp-amber", - "tlp-green", - "tlp-clear" - ], - "Recommendation": "", - "SectionThreatMappings": [ - { - "ReferenceId": "CCC", - "Identifiers": [ - "CCC.MLDE.TH04", - "CCC.TH06" - ] - } - ], - "SectionGuidelineMappings": [ - { - "ReferenceId": "NIST-CSF", - "Identifiers": [ - "PR.IP-12" - ] - }, - { - "ReferenceId": "CCM", - "Identifiers": [ - "TVM-01", - "TVM-02" - ] - }, - { - "ReferenceId": "ISO_27001", - "Identifiers": [ - "2013 A.12.6.1" - ] - }, - { - "ReferenceId": "NIST_800_53", - "Identifiers": [ - "SI-2" - ] - } - ] - } - ], - "Checks": [] - }, - { - "Id": "CCC.MLDE.CN07.AR01", - "Description": "Verify that MLDE instances containing sensitive data cannot be accessed via public IP addresses.", - "Attributes": [ - { - "FamilyName": "Network Security", - "FamilyDescription": "TODO: Describe this control family", - "Section": "", - "SubSection": "CCC.MLDE.CN07 Restrict Public IP Access on MLDE Instances", - "SubSectionObjective": "Prevent public IP access to MLDE instances to reduce exposure to the internet and enhance security.", - "Applicability": [ - "tlp-red" - ], - "Recommendation": "", - "SectionThreatMappings": [ - { - "ReferenceId": "CCC", - "Identifiers": [ - "CCC.MLDE.TH02", - "CCC.VPC.TH02" - ] - } - ], - "SectionGuidelineMappings": [ - { - "ReferenceId": "NIST-CSF", - "Identifiers": [ - "PR.AC-3" - ] - }, - { - "ReferenceId": "CCM", - "Identifiers": [ - "SEF-05" - ] - }, - { - "ReferenceId": "ISO_27001", - "Identifiers": [ - "2013 A.13.1.1" - ] - }, - { - "ReferenceId": "NIST_800_53", - "Identifiers": [ - "SC-7" - ] - } - ] - } - ], - "Checks": [ - "aks_clusters_created_with_private_nodes", - "aks_clusters_public_access_disabled", - "containerregistry_not_publicly_accessible", - "containerregistry_uses_private_link", - "keyvault_private_endpoints", - "keyvault_access_only_through_private_endpoints", - "storage_blob_public_access_level_is_disabled", - "storage_ensure_private_endpoints_in_storage_accounts", - "storage_default_network_access_rule_is_denied", - "network_http_internet_access_restricted", - "network_rdp_internet_access_restricted", - "network_ssh_internet_access_restricted", - "network_udp_internet_access_restricted", - "network_public_ip_shodan" - ] - }, - { - "Id": "CCC.MLDE.CN07.AR02", - "Description": "For MLDE instances without sensitive data requiring public access,\nensure that appropriate security controls are in place and access is approved.", - "Attributes": [ - { - "FamilyName": "Network Security", - "FamilyDescription": "TODO: Describe this control family", - "Section": "CCC.MLDE.CN07 Restrict Public IP Access on MLDE Instances", - "SubSection": "", - "SubSectionObjective": "Prevent public IP access to MLDE instances to reduce exposure to the internet and enhance security.", - "Applicability": [ - "tlp-red", - "tlp-amber", - "tlp-green", - "tlp-clear" - ], - "Recommendation": "", - "SectionThreatMappings": [ - { - "ReferenceId": "CCC", - "Identifiers": [ - "CCC.MLDE.TH02", - "CCC.VPC.TH02" - ] - } - ], - "SectionGuidelineMappings": [ - { - "ReferenceId": "NIST-CSF", - "Identifiers": [ - "PR.AC-3" - ] - }, - { - "ReferenceId": "CCM", - "Identifiers": [ - "SEF-05" - ] - }, - { - "ReferenceId": "ISO_27001", - "Identifiers": [ - "2013 A.13.1.1" - ] - }, - { - "ReferenceId": "NIST_800_53", - "Identifiers": [ - "SC-7" - ] - } - ] - } - ], - "Checks": [ - "aks_clusters_created_with_private_nodes", - "aks_clusters_public_access_disabled", - "containerregistry_not_publicly_accessible", - "containerregistry_uses_private_link", - "keyvault_private_endpoints", - "keyvault_access_only_through_private_endpoints", - "storage_ensure_private_endpoints_in_storage_accounts", - "storage_default_network_access_rule_is_denied", - "network_http_internet_access_restricted", - "network_rdp_internet_access_restricted", - "network_ssh_internet_access_restricted", - "network_udp_internet_access_restricted" - ] - }, - { - "Id": "CCC.MLDE.CN08.AR01", - "Description": "Verify that MLDE instances containing sensitive data can only be deployed in\napproved virtual networks with appropriate security controls.", - "Attributes": [ - { - "FamilyName": "Network Security", - "FamilyDescription": "TODO: Describe this control family", - "Section": "CCC.MLDE.CN08 Restrict Virtual Networks for MLDE Instances", - "SubSection": "", - "SubSectionObjective": "Limit the virtual networks that can be used when creating new MLDE instances to\nensure they are deployed within approved and secure network environments.", - "Applicability": [ - "tlp-red" - ], - "Recommendation": "", - "SectionThreatMappings": [ - { - "ReferenceId": "CCC", - "Identifiers": [ - "CCC.MLDE.TH01", - "CCC.TH01" - ] - } - ], - "SectionGuidelineMappings": [ - { - "ReferenceId": "NIST-CSF", - "Identifiers": [ - "PR.AC-4" - ] - }, - { - "ReferenceId": "CCM", - "Identifiers": [ - "IAM-12" - ] - }, - { - "ReferenceId": "ISO_27001", - "Identifiers": [ - "2013 A.9.1.2" - ] - }, - { - "ReferenceId": "NIST_800_53", - "Identifiers": [ - "AC-6" - ] - } - ] - } - ], - "Checks": [ - "aks_clusters_created_with_private_nodes", - "aks_clusters_public_access_disabled", - "aks_network_policy_enabled", - "app_function_vnet_integration_enabled", - "app_function_not_publicly_accessible", - "containerregistry_not_publicly_accessible", - "containerregistry_uses_private_link", - "keyvault_private_endpoints", - "keyvault_access_only_through_private_endpoints", - "storage_ensure_private_endpoints_in_storage_accounts", - "storage_default_network_access_rule_is_denied", - "network_http_internet_access_restricted", - "network_rdp_internet_access_restricted", - "network_ssh_internet_access_restricted", - "network_udp_internet_access_restricted" - ] - }, - { - "Id": "CCC.MLDE.CN08.AR02", - "Description": "Ensure that MLDE instances without sensitive data are deployed in\nnetworks that meet organizational security standards.", - "Attributes": [ - { - "FamilyName": "Network Security", - "FamilyDescription": "TODO: Describe this control family", - "Section": "CCC.MLDE.CN08 Restrict Virtual Networks for MLDE Instances", - "SubSection": "", - "SubSectionObjective": "Limit the virtual networks that can be used when creating new MLDE instances to\nensure they are deployed within approved and secure network environments.", - "Applicability": [ - "tlp-red", - "tlp-amber", - "tlp-green", - "tlp-clear" - ], - "Recommendation": "", - "SectionThreatMappings": [ - { - "ReferenceId": "CCC", - "Identifiers": [ - "CCC.MLDE.TH01", - "CCC.TH01" - ] - } - ], - "SectionGuidelineMappings": [ - { - "ReferenceId": "NIST-CSF", - "Identifiers": [ - "PR.AC-4" - ] - }, - { - "ReferenceId": "CCM", - "Identifiers": [ - "IAM-12" - ] - }, - { - "ReferenceId": "ISO_27001", - "Identifiers": [ - "2013 A.9.1.2" - ] - }, - { - "ReferenceId": "NIST_800_53", - "Identifiers": [ - "AC-6" - ] - } - ] - } - ], - "Checks": [ - "aks_clusters_created_with_private_nodes", - "aks_clusters_public_access_disabled", - "aks_network_policy_enabled", - "app_function_vnet_integration_enabled", - "containerregistry_not_publicly_accessible", - "containerregistry_uses_private_link", - "keyvault_private_endpoints", - "keyvault_access_only_through_private_endpoints", - "storage_ensure_private_endpoints_in_storage_accounts", - "storage_default_network_access_rule_is_denied", - "storage_ensure_azure_services_are_trusted_to_access_is_enabled", - "network_http_internet_access_restricted", - "network_rdp_internet_access_restricted", - "network_ssh_internet_access_restricted", - "network_udp_internet_access_restricted" - ] - }, - { - "Id": "CCC.Message.CN01.AR01", - "Description": "Attempt to publish a message without using a customer-managed encryption key\nand verify that the message is rejected or not stored.", - "Attributes": [ - { - "FamilyName": "Encryption", - "FamilyDescription": "TODO: Describe this control family", - "Section": "CCC.Message.CN01 Use Customer-Managed Encryption Keys (CMEK) for Messages", - "SubSection": "", - "SubSectionObjective": "Ensure that messages are encrypted using customer-managed encryption keys (CMEK)\nto provide enhanced control over encryption processes and keys, meeting compliance and security requirements.", - "Applicability": [ - "tlp-clear", - "tlp-green", - "tlp-amber", - "tlp-red" - ], - "Recommendation": "", - "SectionThreatMappings": [ - { - "ReferenceId": "CCC", - "Identifiers": [ - "CCC.TH01" - ] - } - ], - "SectionGuidelineMappings": [ - { - "ReferenceId": "NIST-CSF", - "Identifiers": [ - "PR.DS-1" - ] - }, - { - "ReferenceId": "NIST_800_53", - "Identifiers": [ - "SC-12", - "SC-13" - ] - } - ] - } - ], - "Checks": [ - "storage_ensure_encryption_with_customer_managed_keys", - "monitor_storage_account_with_activity_logs_cmk_encrypted" - ] - }, { "Id": "CCC.Monitor.CN01.AR01", - "Description": "When an External Monitoring system exceeds the anticipated rate of monitoring checks then\nRate Limiting MUST be applied and an Audit Alert MUST be generated.", + "Description": "When an External Monitoring system exceeds the anticipated rate of monitoring checks then Rate Limiting MUST be applied and an Audit Alert MUST be generated.", "Attributes": [ { "FamilyName": "Logging & Monitoring", @@ -4698,7 +2987,7 @@ }, { "Id": "CCC.Monitor.CN02.AR01", - "Description": "When an Custom or User-Defined Metric starts to flood a collector, then a rate limit MUST be applied\nto reduce the network impact of traffic and an alert must triggered.", + "Description": "When an Custom or User-Defined Metric starts to flood a collector, then a rate limit MUST be applied to reduce the network impact of traffic and an alert must triggered.", "Attributes": [ { "FamilyName": "Logging & Monitoring", @@ -4745,14 +3034,14 @@ }, { "Id": "CCC.Monitor.CN03.AR01", - "Description": "When external systems have approved access to internal systems not normally available for public access\nthen they MUST be secured to prevent unauthorised access jumping through to the internal systems and\nonly allow access to specific internal services.", + "Description": "When external systems have approved access to internal systems not normally available for public access then they MUST be secured to prevent unauthorised access jumping through to the internal systems and only allow access to specific internal services.", "Attributes": [ { "FamilyName": "Identity and Access Management", "FamilyDescription": "Controls designed to prevent unauthorised access to monitoring features.", "Section": "CCC.Monitor.CN03 Access External Monitoring", "SubSection": "", - "SubSectionObjective": "Control access to Synthetic monitoring solutions using API keys or Certificate based authentication to\nensure they don't become an attack path, preventing monitoring systems from forging network requests to\ngain access to internal systems.", + "SubSectionObjective": "Control access to Synthetic monitoring solutions using API keys or Certificate based authentication to ensure they don't become an attack path, preventing monitoring systems from forging network requests to gain access to internal systems.", "Applicability": [ "tlp-clear", "tlp-green", @@ -4793,7 +3082,7 @@ }, { "Id": "CCC.Monitor.CN04.AR01", - "Description": "When monitoring dashboards display degraded services which may become potential targets then the\ndashboard MUST be protected from unauthorised access.", + "Description": "When monitoring dashboards display degraded services which may become potential targets then the dashboard MUST be protected from unauthorised access.", "Attributes": [ { "FamilyName": "Identity and Access Management", @@ -4838,7 +3127,7 @@ }, { "Id": "CCC.Monitor.CN05.AR01", - "Description": "When monitoring services have generated an alert, the service MUST ensure only authorised\nresponders silence or acknowledge the alert.", + "Description": "When monitoring services have generated an alert, the service MUST ensure only authorised responders silence or acknowledge the alert.", "Attributes": [ { "FamilyName": "Identity and Access Management", @@ -4889,7 +3178,7 @@ "FamilyDescription": "Controls designed to prevent unauthorised access to monitoring features.", "Section": "CCC.Monitor.CN06 Metrics pushed for authorised services only", "SubSection": "", - "SubSectionObjective": "Use IAM to control which types of metrics or traces can be pushed by different system to avoid a compromised\nsystem pushing fabricated metrics about a different service", + "SubSectionObjective": "Use IAM to control which types of metrics or traces can be pushed by different system to avoid a compromised system pushing fabricated metrics about a different service", "Applicability": [ "tlp-clear", "tlp-green", @@ -4930,201 +3219,16 @@ "app_ensure_auth_is_set_up" ] }, - { - "Id": "CCC.SecMgmt.CN01.AR01", - "Description": "Attempt to use an outdated version of a secret after its rotation period\nhas passed and verify that access is denied.", - "Attributes": [ - { - "FamilyName": "Data Protection", - "FamilyDescription": "TODO: Describe this control family", - "Section": "CCC.SecMgmt.CN01 Enforce Automatic Secret Rotation", - "SubSection": "", - "SubSectionObjective": "Ensure that secrets are automatically rotated on a defined schedule to\nreduce the risk of secret compromise and unauthorized access.", - "Applicability": [ - "tlp-red", - "tlp-amber" - ], - "Recommendation": "", - "SectionThreatMappings": [ - { - "ReferenceId": "CCC", - "Identifiers": [ - "CCC.TH01", - "CCC.TH14" - ] - } - ], - "SectionGuidelineMappings": [ - { - "ReferenceId": "NIST-CSF", - "Identifiers": [ - "PR.DS-6" - ] - }, - { - "ReferenceId": "NIST_800_53", - "Identifiers": [ - "SC-12", - "SC-28" - ] - } - ] - } - ], - "Checks": [ - "keyvault_key_rotation_enabled", - "storage_key_rotation_90_days" - ] - }, - { - "Id": "CCC.SecMgmt.CN02.AR01", - "Description": "Attempt to retrieve a secret from an unauthorized region and verify that access is denied.", - "Attributes": [ - { - "FamilyName": "Data Protection", - "FamilyDescription": "TODO: Describe this control family", - "Section": "CCC.SecMgmt.CN02 Enforce Secret Replication Policies", - "SubSection": "", - "SubSectionObjective": "Ensure that secrets are replicated only to authorized locations as per\norganizational data residency and compliance requirements.", - "Applicability": [ - "tlp-red", - "tlp-amber" - ], - "Recommendation": "", - "SectionThreatMappings": [ - { - "ReferenceId": "CCC", - "Identifiers": [ - "CCC.TH03", - "CCC.TH04" - ] - } - ], - "SectionGuidelineMappings": [ - { - "ReferenceId": "NIST-CSF", - "Identifiers": [ - "PR.DS-5" - ] - }, - { - "ReferenceId": "NIST_800_53", - "Identifiers": [ - "AC-3", - "SC-7" - ] - } - ] - } - ], - "Checks": [ - "keyvault_private_endpoints", - "keyvault_access_only_through_private_endpoints", - "keyvault_rbac_enabled", - "keyvault_logging_enabled" - ] - }, - { - "Id": "CCC.SvlsComp.CN01.AR01", - "Description": "Attempt to access the serverless function over the public internet and verify that access is denied.", - "Attributes": [ - { - "FamilyName": "Network Security", - "FamilyDescription": "TODO: Describe this control family", - "Section": "CCC.SvlsComp.CN01 Enforce Use of Private Endpoints for Serverless Function", - "SubSection": "", - "SubSectionObjective": "Ensure that the serverless function is accessible only through a private endpoint,\nallowing it to communicate securely within a virtual private network and preventing\nunauthorized external access.", - "Applicability": [ - "tlp-red", - "tlp-amber" - ], - "Recommendation": "", - "SectionThreatMappings": [ - { - "ReferenceId": "CCC", - "Identifiers": [ - "CCC.TH01" - ] - } - ], - "SectionGuidelineMappings": [ - { - "ReferenceId": "NIST-CSF", - "Identifiers": [ - "PR.AC-5" - ] - }, - { - "ReferenceId": "NIST_800_53", - "Identifiers": [ - "SC-7", - "SC-8" - ] - } - ] - } - ], - "Checks": [ - "app_function_not_publicly_accessible", - "app_function_vnet_integration_enabled" - ] - }, - { - "Id": "CCC.SvlsComp.CN02.AR01", - "Description": "Send requests to invoke the function up to the allowed threshold and confirm they\nare successful; then send additional requests exceeding the threshold from the same\nentity and verify that they are denied.", - "Attributes": [ - { - "FamilyName": "Availability", - "FamilyDescription": "TODO: Describe this control family", - "Section": "CCC.SvlsComp.CN02 Implement Function Invocation Rate Limits", - "SubSection": "", - "SubSectionObjective": "Ensure that function invocation is limited to a specified threshold from any single entity,\npreventing resource exhaustion and denial of service attacks.", - "Applicability": [ - "tlp-red", - "tlp-amber" - ], - "Recommendation": "", - "SectionThreatMappings": [ - { - "ReferenceId": "CCC", - "Identifiers": [ - "CCC.TH12" - ] - } - ], - "SectionGuidelineMappings": [ - { - "ReferenceId": "NIST-CSF", - "Identifiers": [ - "PR.DS-4" - ] - }, - { - "ReferenceId": "NIST_800_53", - "Identifiers": [ - "SC-5" - ] - } - ] - } - ], - "Checks": [ - "app_function_access_keys_configured", - "app_function_not_publicly_accessible", - "app_function_vnet_integration_enabled", - "app_function_identity_is_configured" - ] - }, { "Id": "CCC.VPC.CN01.AR01", - "Description": "When a subscription is created, the subscription MUST NOT\ncontain default network resources.", + "Description": "When a subscription is created, the subscription MUST NOT contain default network resources.", "Attributes": [ { "FamilyName": "Network Security", "FamilyDescription": "TODO: Describe this control family", "Section": "CCC.VPC.CN01 Restrict Default Network Creation", "SubSection": "", - "SubSectionObjective": "Restrict the automatic creation of default virtual networks and related\nresources during subscription initialization to avoid insecure default\nconfigurations and enforce custom network policies.", + "SubSectionObjective": "Restrict the automatic creation of default virtual networks and related resources during subscription initialization to avoid insecure default configurations and enforce custom network policies.", "Applicability": [ "tlp-amber", "tlp-red" @@ -5168,86 +3272,16 @@ ], "Checks": [] }, - { - "Id": "CCC.VPC.CN02.AR01", - "Description": "When a resource is created in a public subnet, that resource\nMUST NOT be assigned an external IP address by default.", - "Attributes": [ - { - "FamilyName": "Network Security", - "FamilyDescription": "TODO: Describe this control family", - "Section": "CCC.VPC.CN02 Limit Resource Creation in Public Subnet", - "SubSection": "", - "SubSectionObjective": "Restrict the creation of resources in the public subnet with\ndirect access to the internet to minimize attack surfaces.", - "Applicability": [ - "tlp-red" - ], - "Recommendation": "", - "SectionThreatMappings": [ - { - "ReferenceId": "CCC", - "Identifiers": [ - "CCC.VPC.TH02" - ] - } - ], - "SectionGuidelineMappings": [ - { - "ReferenceId": "NIST-CSF", - "Identifiers": [ - "PR.AC-3" - ] - }, - { - "ReferenceId": "CCM", - "Identifiers": [ - "SEF-05" - ] - }, - { - "ReferenceId": "ISO_27001", - "Identifiers": [ - "2013 A.13.1.1" - ] - }, - { - "ReferenceId": "NIST_800_53", - "Identifiers": [ - "AC-4" - ] - } - ] - } - ], - "Checks": [ - "aks_clusters_public_access_disabled", - "aks_clusters_created_with_private_nodes", - "network_http_internet_access_restricted", - "network_rdp_internet_access_restricted", - "network_ssh_internet_access_restricted", - "network_udp_internet_access_restricted", - "containerregistry_not_publicly_accessible", - "containerregistry_uses_private_link", - "keyvault_private_endpoints", - "keyvault_access_only_through_private_endpoints", - "cosmosdb_account_use_private_endpoints", - "cosmosdb_account_firewall_use_selected_networks", - "storage_ensure_private_endpoints_in_storage_accounts", - "storage_default_network_access_rule_is_denied", - "storage_blob_public_access_level_is_disabled", - "sqlserver_unrestricted_inbound_access", - "app_function_not_publicly_accessible" - ] - }, { "Id": "CCC.VPC.CN03.AR01", - "Description": "When a VPC peering connection is requested, the service MUST\nprevent connections from VPCs that are not explicitly\nallowed.", + "Description": "When a VPC peering connection is requested, the service MUST prevent connections from VPCs that are not explicitly allowed.", "Attributes": [ { "FamilyName": "Network Security", "FamilyDescription": "TODO: Describe this control family", "Section": "CCC.VPC.CN03 Restrict VPC Peering to Authorized Accounts", "SubSection": "", - "SubSectionObjective": "Ensure VPC peering connections are only established with explicitly\nauthorized destinations to limit network exposure and enforce boundary\ncontrols.", + "SubSectionObjective": "Ensure VPC peering connections are only established with explicitly authorized destinations to limit network exposure and enforce boundary controls.", "Applicability": [ "tlp-green", "tlp-amber", @@ -5294,14 +3328,14 @@ }, { "Id": "CCC.VPC.CN04.AR01", - "Description": "When any network traffic goes to or from an interface in the VPC,\nthe service MUST capture and log all relevant information.", + "Description": "When any network traffic goes to or from an interface in the VPC, the service MUST capture and log all relevant information.", "Attributes": [ { "FamilyName": "Network Security", "FamilyDescription": "TODO: Describe this control family", "Section": "CCC.VPC.CN04 Enforce VPC Flow Logs on VPCs", "SubSection": "", - "SubSectionObjective": "Ensure VPCs are configured with flow logs enabled to capture traffic\ninformation.", + "SubSectionObjective": "Ensure VPCs are configured with flow logs enabled to capture traffic information.", "Applicability": [ "tlp-amber", "tlp-red" @@ -5351,14 +3385,14 @@ }, { "Id": "CCC.Vector.CN01.AR01", - "Description": "When a vector embedding is submitted for indexing, the system MUST validate that it\nmatches expected schema, dimension, and format profiles.", + "Description": "When a vector embedding is submitted for indexing, the system MUST validate that it matches expected schema, dimension, and format profiles.", "Attributes": [ { "FamilyName": "Vector Indexing", "FamilyDescription": "Controls specific to the management and protection of vector embedding and index operations.", "Section": "CCC.Vector.CN01 Validate Embeddings Before Indexing", "SubSection": "", - "SubSectionObjective": "Ensure all incoming embeddings are structurally and statistically validated\nbefore indexing to prevent poisoning or corruption.", + "SubSectionObjective": "Ensure all incoming embeddings are structurally and statistically validated before indexing to prevent poisoning or corruption.", "Applicability": [ "tlp-clear", "tlp-green", @@ -5390,14 +3424,14 @@ }, { "Id": "CCC.Vector.CN02.AR01", - "Description": "When an index lifecycle event is triggered, the service MUST\nverify that the actor has explicit permissions for the operation type.", + "Description": "When an index lifecycle event is triggered, the service MUST verify that the actor has explicit permissions for the operation type.", "Attributes": [ { "FamilyName": "Vector Indexing", "FamilyDescription": "Controls specific to the management and protection of vector embedding and index operations.", "Section": "CCC.Vector.CN02 Enforce Role-Based Index Lifecycle Management", "SubSection": "", - "SubSectionObjective": "Restrict index lifecycle operations (create, delete, rollback) to privileged\nidentities using fine-grained access controls.", + "SubSectionObjective": "Restrict index lifecycle operations (create, delete, rollback) to privileged identities using fine-grained access controls.", "Applicability": [ "tlp-clear", "tlp-green", @@ -5435,14 +3469,14 @@ }, { "Id": "CCC.Vector.CN03.AR01", - "Description": "When a metadata filter is applied to a query, the service MUST\nverify the requester is authorized to access that field.", + "Description": "When a metadata filter is applied to a query, the service MUST verify the requester is authorized to access that field.", "Attributes": [ { "FamilyName": "Vector Indexing", "FamilyDescription": "Controls specific to the management and protection of vector embedding and index operations.", "Section": "CCC.Vector.CN03 Enforce Metadata-Level Access Controls", "SubSection": "", - "SubSectionObjective": "Apply access control policies to metadata fields used in filtering to\nprevent unauthorized exposure or inference.", + "SubSectionObjective": "Apply access control policies to metadata fields used in filtering to prevent unauthorized exposure or inference.", "Applicability": [ "tlp-amber", "tlp-red" @@ -5469,49 +3503,18 @@ ] } ], - "Checks": [ - "app_function_not_publicly_accessible", - "app_function_identity_is_configured", - "app_function_identity_without_admin_privileges", - "app_function_access_keys_configured", - "containerregistry_not_publicly_accessible", - "containerregistry_uses_private_link", - "containerregistry_admin_user_disabled", - "cosmosdb_account_firewall_use_selected_networks", - "cosmosdb_account_use_private_endpoints", - "cosmosdb_account_use_aad_and_rbac", - "keyvault_rbac_enabled", - "keyvault_private_endpoints", - "keyvault_access_only_through_private_endpoints", - "keyvault_logging_enabled", - "storage_blob_public_access_level_is_disabled", - "storage_default_network_access_rule_is_denied", - "storage_ensure_private_endpoints_in_storage_accounts", - "storage_account_key_access_disabled", - "storage_secure_transfer_required_is_enabled", - "storage_ensure_encryption_with_customer_managed_keys", - "storage_ensure_soft_delete_is_enabled", - "storage_ensure_file_shares_soft_delete_is_enabled", - "iam_role_user_access_admin_restricted", - "iam_custom_role_has_permissions_to_administer_resource_locks", - "network_http_internet_access_restricted", - "network_rdp_internet_access_restricted", - "network_ssh_internet_access_restricted", - "network_udp_internet_access_restricted", - "aks_clusters_public_access_disabled", - "aks_network_policy_enabled" - ] + "Checks": [] }, { "Id": "CCC.Vector.CN04.AR01", - "Description": "When ingestion exceeds pre-defined thresholds, the service MUST\nthrottle or reject excess vector write operations.", + "Description": "When ingestion exceeds pre-defined thresholds, the service MUST throttle or reject excess vector write operations.", "Attributes": [ { "FamilyName": "Vector Indexing", "FamilyDescription": "Controls specific to the management and protection of vector embedding and index operations.", "Section": "CCC.Vector.CN04 Enforce Ingestion Quotas and Throttling", "SubSection": "", - "SubSectionObjective": "Prevent ingestion-based DoS or index pollution by\nrate-limiting vector submissions and enforcing quotas.", + "SubSectionObjective": "Prevent ingestion-based DoS or index pollution by rate-limiting vector submissions and enforcing quotas.", "Applicability": [ "tlp-green", "tlp-amber", @@ -5541,14 +3544,14 @@ }, { "Id": "CCC.Vector.CN05.AR01", - "Description": "When a rollback is attempted, the system MUST log\nthe action and verify rollback authorization.", + "Description": "When a rollback is attempted, the system MUST log the action and verify rollback authorization.", "Attributes": [ { "FamilyName": "Vector Indexing", "FamilyDescription": "Controls specific to the management and protection of vector embedding and index operations.", "Section": "CCC.Vector.CN05 Enforce Index Versioning with Rollback Protection", "SubSection": "", - "SubSectionObjective": "Ensure vector indexes are versioned and that rollback\noperations are authorized and auditable.", + "SubSectionObjective": "Ensure vector indexes are versioned and that rollback operations are authorized and auditable.", "Applicability": [ "tlp-amber", "tlp-red" @@ -5578,14 +3581,14 @@ }, { "Id": "CCC.Vector.CN06.AR01", - "Description": "When an embedding is submitted, the service MUST validate\nthat its format and dimensionality match allowed profiles.", + "Description": "When an embedding is submitted, the service MUST validate that its format and dimensionality match allowed profiles.", "Attributes": [ { "FamilyName": "Vector Indexing", "FamilyDescription": "Controls specific to the management and protection of vector embedding and index operations.", "Section": "CCC.Vector.CN06 Enforce Dimensional and Format Constraints", "SubSection": "", - "SubSectionObjective": "Reject embeddings that do not conform to expected model\nspecifications (dimensions, format, etc).", + "SubSectionObjective": "Reject embeddings that do not conform to expected model specifications (dimensions, format, etc).", "Applicability": [ "tlp-clear", "tlp-green", @@ -5616,14 +3619,14 @@ }, { "Id": "CCC.Vector.CN07.AR01", - "Description": "When a search request is issued, clients MUST be allowed\nto declare their requirement for exact vs approximate results.", + "Description": "When a search request is issued, clients MUST be allowed to declare their requirement for exact vs approximate results.", "Attributes": [ { "FamilyName": "Vector Indexing", "FamilyDescription": "Controls specific to the management and protection of vector embedding and index operations.", "Section": "CCC.Vector.CN07 Support Explicit ANN vs. Exact Search Configuration", "SubSection": "", - "SubSectionObjective": "Provide clients with the option to enforce exact-match\n(non-ANN) search where search fidelity is critical.", + "SubSectionObjective": "Provide clients with the option to enforce exact-match (non-ANN) search where search fidelity is critical.", "Applicability": [ "tlp-amber", "tlp-red" @@ -5644,20 +3647,20 @@ }, { "Id": "CCC.Core.CN01.AR01", - "Description": "When a port is exposed for non-SSH network traffic, all traffic\nMUST include a TLS handshake AND be encrypted using TLS 1.3 or\nhigher.", + "Description": "When a port is exposed for non-SSH network traffic, all traffic MUST include a TLS handshake AND be encrypted using TLS 1.3 or higher.", "Attributes": [ { "FamilyName": "Data", - "FamilyDescription": "The Data control family ensures the confidentiality, integrity,\navailability, and sovereignty of data across its lifecycle.\nThese controls govern how data is transmitted, stored,\nreplicated, and protected from unauthorized access, tampering,\nor exposure beyond defined trust perimeters.\n", + "FamilyDescription": "The Data control family ensures the confidentiality, integrity, availability, and sovereignty of data across its lifecycle. These controls govern how data is transmitted, stored, replicated, and protected from unauthorized access, tampering, or exposure beyond defined trust perimeters. ", "Section": "CCC.Core.CN01 Encrypt Data for Transmission", "SubSection": "", - "SubSectionObjective": "Ensure that all communications are encrypted in transit to protect\ndata integrity and confidentiality.", + "SubSectionObjective": "Ensure that all communications are encrypted in transit to protect data integrity and confidentiality.", "Applicability": [ "tlp-green", "tlp-amber", "tlp-red" ], - "Recommendation": "Most cloud services enable TLS 1.3 by default. Where it is not\nalready set, ensure that your services are configured or updated\naccordingly.\n", + "Recommendation": "Most cloud services enable TLS 1.3 by default. Where it is not already set, ensure that your services are configured or updated accordingly. ", "SectionThreatMappings": [ { "ReferenceId": "CCC", @@ -5707,21 +3710,21 @@ }, { "Id": "CCC.Core.CN01.AR02", - "Description": "When a port is exposed for SSH network traffic, all traffic MUST\ninclude a SSH handshake AND be encrypted using SSHv2 or higher.", + "Description": "When a port is exposed for SSH network traffic, all traffic MUST include a SSH handshake AND be encrypted using SSHv2 or higher.", "Attributes": [ { "FamilyName": "Data", - "FamilyDescription": "The Data control family ensures the confidentiality, integrity,\navailability, and sovereignty of data across its lifecycle.\nThese controls govern how data is transmitted, stored,\nreplicated, and protected from unauthorized access, tampering,\nor exposure beyond defined trust perimeters.\n", + "FamilyDescription": "The Data control family ensures the confidentiality, integrity, availability, and sovereignty of data across its lifecycle. These controls govern how data is transmitted, stored, replicated, and protected from unauthorized access, tampering, or exposure beyond defined trust perimeters. ", "Section": "CCC.Core.CN01 Encrypt Data for Transmission", "SubSection": "", - "SubSectionObjective": "Ensure that all communications are encrypted in transit to protect\ndata integrity and confidentiality.", + "SubSectionObjective": "Ensure that all communications are encrypted in transit to protect data integrity and confidentiality.", "Applicability": [ "tlp-clear", "tlp-green", "tlp-amber", "tlp-red" ], - "Recommendation": "Any time port 22 is exposed, ensure that it has a properly\nimplemented SSH server with SSHv2 enabled and configured with\nstrong ciphers.\n", + "Recommendation": "Any time port 22 is exposed, ensure that it has a properly implemented SSH server with SSHv2 enabled and configured with strong ciphers. ", "SectionThreatMappings": [ { "ReferenceId": "CCC", @@ -5773,20 +3776,20 @@ }, { "Id": "CCC.Core.CN01.AR03", - "Description": "When the service receives unencrypted traffic, \nthen it MUST either block the request or automatically\nredirect it to the secure equivalent.", + "Description": "When the service receives unencrypted traffic, then it MUST either block the request or automatically redirect it to the secure equivalent.", "Attributes": [ { "FamilyName": "Data", - "FamilyDescription": "The Data control family ensures the confidentiality, integrity,\navailability, and sovereignty of data across its lifecycle.\nThese controls govern how data is transmitted, stored,\nreplicated, and protected from unauthorized access, tampering,\nor exposure beyond defined trust perimeters.\n", + "FamilyDescription": "The Data control family ensures the confidentiality, integrity, availability, and sovereignty of data across its lifecycle. These controls govern how data is transmitted, stored, replicated, and protected from unauthorized access, tampering, or exposure beyond defined trust perimeters. ", "Section": "CCC.Core.CN01 Encrypt Data for Transmission", "SubSection": "", - "SubSectionObjective": "Ensure that all communications are encrypted in transit to protect\ndata integrity and confidentiality.", + "SubSectionObjective": "Ensure that all communications are encrypted in transit to protect data integrity and confidentiality.", "Applicability": [ "tlp-green", "tlp-amber", "tlp-red" ], - "Recommendation": "Review firewall, load balancer, and application configurations to\nensure insecure protocols such as HTTP, FTP, and Telnet are not\nexposed. Where possible, implement automatic redirection to secure\nprotocols such as HTTPS, SFTP, SSH, and regularly scan for\nprotocol drift.\n", + "Recommendation": "Review firewall, load balancer, and application configurations to ensure insecure protocols such as HTTP, FTP, and Telnet are not exposed. Where possible, implement automatic redirection to secure protocols such as HTTPS, SFTP, SSH, and regularly scan for protocol drift. ", "SectionThreatMappings": [ { "ReferenceId": "CCC", @@ -5837,21 +3840,21 @@ }, { "Id": "CCC.Core.CN01.AR07", - "Description": "When a port is exposed, the service MUST ensure that the protocol\nand service officially assigned to that port number by the IANA\nService Name and Transport Protocol Port Number Registry, and no\nother, is run on that port.", + "Description": "When a port is exposed, the service MUST ensure that the protocol and service officially assigned to that port number by the IANA Service Name and Transport Protocol Port Number Registry, and no other, is run on that port.", "Attributes": [ { "FamilyName": "Data", - "FamilyDescription": "The Data control family ensures the confidentiality, integrity,\navailability, and sovereignty of data across its lifecycle.\nThese controls govern how data is transmitted, stored,\nreplicated, and protected from unauthorized access, tampering,\nor exposure beyond defined trust perimeters.\n", + "FamilyDescription": "The Data control family ensures the confidentiality, integrity, availability, and sovereignty of data across its lifecycle. These controls govern how data is transmitted, stored, replicated, and protected from unauthorized access, tampering, or exposure beyond defined trust perimeters. ", "Section": "CCC.Core.CN01 Encrypt Data for Transmission", "SubSection": "", - "SubSectionObjective": "Ensure that all communications are encrypted in transit to protect\ndata integrity and confidentiality.", + "SubSectionObjective": "Ensure that all communications are encrypted in transit to protect data integrity and confidentiality.", "Applicability": [ "tlp-clear", "tlp-green", "tlp-amber", "tlp-red" ], - "Recommendation": "Reference the IANA Service Name and Transport Protocol Port Number\nRegistry for more information about correct protocol-to-port\nassignments. Avoid running non-standard services on well-known\nports.\n", + "Recommendation": "Reference the IANA Service Name and Transport Protocol Port Number Registry for more information about correct protocol-to-port assignments. Avoid running non-standard services on well-known ports. ", "SectionThreatMappings": [ { "ReferenceId": "CCC", @@ -5904,19 +3907,19 @@ }, { "Id": "CCC.Core.CN01.AR08", - "Description": "When a service transmits data using TLS, mutual TLS (mTLS) MUST be\nimplemented to require both client and server certificate\nauthentication for all connections.", + "Description": "When a service transmits data using TLS, mutual TLS (mTLS) MUST be implemented to require both client and server certificate authentication for all connections.", "Attributes": [ { "FamilyName": "Data", - "FamilyDescription": "The Data control family ensures the confidentiality, integrity,\navailability, and sovereignty of data across its lifecycle.\nThese controls govern how data is transmitted, stored,\nreplicated, and protected from unauthorized access, tampering,\nor exposure beyond defined trust perimeters.\n", + "FamilyDescription": "The Data control family ensures the confidentiality, integrity, availability, and sovereignty of data across its lifecycle. These controls govern how data is transmitted, stored, replicated, and protected from unauthorized access, tampering, or exposure beyond defined trust perimeters. ", "Section": "CCC.Core.CN01 Encrypt Data for Transmission", "SubSection": "", - "SubSectionObjective": "Ensure that all communications are encrypted in transit to protect\ndata integrity and confidentiality.", + "SubSectionObjective": "Ensure that all communications are encrypted in transit to protect data integrity and confidentiality.", "Applicability": [ "tlp-amber", "tlp-red" ], - "Recommendation": "Configure mTLS for all endpoints that process or transmit\nsensitive data. Ensure both client and server certificates are\nvalidated and managed securely. Regularly review certificate\nauthorities and automate certificate rotation where possible.\n", + "Recommendation": "Configure mTLS for all endpoints that process or transmit sensitive data. Ensure both client and server certificates are validated and managed securely. Regularly review certificate authorities and automate certificate rotation where possible. ", "SectionThreatMappings": [ { "ReferenceId": "CCC", @@ -5965,21 +3968,21 @@ }, { "Id": "CCC.Core.CN13.AR01", - "Description": "When a port is exposed that uses certificate-based encryption,\nthe service MUST only use valid, unexpired certificates issued by\na trusted certificate authority.", + "Description": "When a port is exposed that uses certificate-based encryption, the service MUST only use valid, unexpired certificates issued by a trusted certificate authority.", "Attributes": [ { "FamilyName": "Data", - "FamilyDescription": "The Data control family ensures the confidentiality, integrity,\navailability, and sovereignty of data across its lifecycle.\nThese controls govern how data is transmitted, stored,\nreplicated, and protected from unauthorized access, tampering,\nor exposure beyond defined trust perimeters.\n", + "FamilyDescription": "The Data control family ensures the confidentiality, integrity, availability, and sovereignty of data across its lifecycle. These controls govern how data is transmitted, stored, replicated, and protected from unauthorized access, tampering, or exposure beyond defined trust perimeters. ", "Section": "CCC.Core.CN13 Minimize Lifetime of Encryption and Authentication Certificates", "SubSection": "", - "SubSectionObjective": "Ensure that encryption and authentication certificates have a limited\nlifetime to reduce the risk of compromise and ensure the use of\nup-to-date security practices.", + "SubSectionObjective": "Ensure that encryption and authentication certificates have a limited lifetime to reduce the risk of compromise and ensure the use of up-to-date security practices.", "Applicability": [ "tlp-clear", "tlp-green", "tlp-amber", "tlp-red" ], - "Recommendation": "Track certificate expiration dates and automate certificate\nrenewal where possible. Use certificate management tools to ensure\nonly certificates from trusted authorities are deployed.\n", + "Recommendation": "Track certificate expiration dates and automate certificate renewal where possible. Use certificate management tools to ensure only certificates from trusted authorities are deployed. ", "SectionThreatMappings": [ { "ReferenceId": "CCC", @@ -6003,18 +4006,18 @@ }, { "Id": "CCC.Core.CN13.AR02", - "Description": "When a port is exposed that uses certificate-based encryption,\nthe service MUST rotate active certificates within 180 days of\nissuance.", + "Description": "When a port is exposed that uses certificate-based encryption, the service MUST rotate active certificates within 180 days of issuance.", "Attributes": [ { "FamilyName": "Data", - "FamilyDescription": "The Data control family ensures the confidentiality, integrity,\navailability, and sovereignty of data across its lifecycle.\nThese controls govern how data is transmitted, stored,\nreplicated, and protected from unauthorized access, tampering,\nor exposure beyond defined trust perimeters.\n", + "FamilyDescription": "The Data control family ensures the confidentiality, integrity, availability, and sovereignty of data across its lifecycle. These controls govern how data is transmitted, stored, replicated, and protected from unauthorized access, tampering, or exposure beyond defined trust perimeters. ", "Section": "CCC.Core.CN13 Minimize Lifetime of Encryption and Authentication Certificates", "SubSection": "", - "SubSectionObjective": "Ensure that encryption and authentication certificates have a limited\nlifetime to reduce the risk of compromise and ensure the use of\nup-to-date security practices.", + "SubSectionObjective": "Ensure that encryption and authentication certificates have a limited lifetime to reduce the risk of compromise and ensure the use of up-to-date security practices.", "Applicability": [ "tlp-amber" ], - "Recommendation": "Track certificate expiration dates and automate certificate\nrenewal where possible. Use certificate management tools to ensure\nonly certificates from trusted authorities are deployed.\n", + "Recommendation": "Track certificate expiration dates and automate certificate renewal where possible. Use certificate management tools to ensure only certificates from trusted authorities are deployed. ", "SectionThreatMappings": [ { "ReferenceId": "CCC", @@ -6037,18 +4040,18 @@ }, { "Id": "CCC.Core.CN13.AR03", - "Description": "When a port is exposed that uses certificate-based encryption,\nthe service MUST rotate active certificates within 90 days of\nissuance.", + "Description": "When a port is exposed that uses certificate-based encryption, the service MUST rotate active certificates within 90 days of issuance.", "Attributes": [ { "FamilyName": "Data", - "FamilyDescription": "The Data control family ensures the confidentiality, integrity,\navailability, and sovereignty of data across its lifecycle.\nThese controls govern how data is transmitted, stored,\nreplicated, and protected from unauthorized access, tampering,\nor exposure beyond defined trust perimeters.\n", + "FamilyDescription": "The Data control family ensures the confidentiality, integrity, availability, and sovereignty of data across its lifecycle. These controls govern how data is transmitted, stored, replicated, and protected from unauthorized access, tampering, or exposure beyond defined trust perimeters. ", "Section": "CCC.Core.CN13 Minimize Lifetime of Encryption and Authentication Certificates", "SubSection": "", - "SubSectionObjective": "Ensure that encryption and authentication certificates have a limited\nlifetime to reduce the risk of compromise and ensure the use of\nup-to-date security practices.", + "SubSectionObjective": "Ensure that encryption and authentication certificates have a limited lifetime to reduce the risk of compromise and ensure the use of up-to-date security practices.", "Applicability": [ "tlp-red" ], - "Recommendation": "Track certificate expiration dates and automate certificate\nrenewal where possible. Use certificate management tools to ensure\nonly certificates from trusted authorities are deployed.\n", + "Recommendation": "Track certificate expiration dates and automate certificate renewal where possible. Use certificate management tools to ensure only certificates from trusted authorities are deployed. ", "SectionThreatMappings": [ { "ReferenceId": "CCC", @@ -6068,21 +4071,21 @@ }, { "Id": "CCC.Core.CN06.AR01", - "Description": "When the service is running, its region and availability zone MUST\nbe included in a list of explicitly trusted or approved locations\nwithin the trust perimeter.", + "Description": "When the service is running, its region and availability zone MUST be included in a list of explicitly trusted or approved locations within the trust perimeter.", "Attributes": [ { "FamilyName": "Data", - "FamilyDescription": "The Data control family ensures the confidentiality, integrity,\navailability, and sovereignty of data across its lifecycle.\nThese controls govern how data is transmitted, stored,\nreplicated, and protected from unauthorized access, tampering,\nor exposure beyond defined trust perimeters.\n", + "FamilyDescription": "The Data control family ensures the confidentiality, integrity, availability, and sovereignty of data across its lifecycle. These controls govern how data is transmitted, stored, replicated, and protected from unauthorized access, tampering, or exposure beyond defined trust perimeters. ", "Section": "CCC.Core.CN06 Restrict Deployments to Trust Perimeter", "SubSection": "", - "SubSectionObjective": "Ensure that the service and its child resources are only deployed on\ninfrastructure in locations that are explicitly included within a\ndefined trust perimeter.", + "SubSectionObjective": "Ensure that the service and its child resources are only deployed on infrastructure in locations that are explicitly included within a defined trust perimeter.", "Applicability": [ "tlp-clear", "tlp-green", "tlp-amber", "tlp-red" ], - "Recommendation": "Maintain an up-to-date list of trusted and approved regions based\non organizational policies. Validate the service's deployment\nlocation is included in this list.\n", + "Recommendation": "Maintain an up-to-date list of trusted and approved regions based on organizational policies. Validate the service's deployment location is included in this list. ", "SectionThreatMappings": [ { "ReferenceId": "CCC", @@ -6137,21 +4140,21 @@ }, { "Id": "CCC.Core.CN06.AR02", - "Description": "When a child resource is deployed, its region and availability\nzone MUST be included in a list of explicitly trusted or approved\nlocations within the trust perimeter.", + "Description": "When a child resource is deployed, its region and availability zone MUST be included in a list of explicitly trusted or approved locations within the trust perimeter.", "Attributes": [ { "FamilyName": "Data", - "FamilyDescription": "The Data control family ensures the confidentiality, integrity,\navailability, and sovereignty of data across its lifecycle.\nThese controls govern how data is transmitted, stored,\nreplicated, and protected from unauthorized access, tampering,\nor exposure beyond defined trust perimeters.\n", + "FamilyDescription": "The Data control family ensures the confidentiality, integrity, availability, and sovereignty of data across its lifecycle. These controls govern how data is transmitted, stored, replicated, and protected from unauthorized access, tampering, or exposure beyond defined trust perimeters. ", "Section": "CCC.Core.CN06 Restrict Deployments to Trust Perimeter", "SubSection": "", - "SubSectionObjective": "Ensure that the service and its child resources are only deployed on\ninfrastructure in locations that are explicitly included within a\ndefined trust perimeter.", + "SubSectionObjective": "Ensure that the service and its child resources are only deployed on infrastructure in locations that are explicitly included within a defined trust perimeter.", "Applicability": [ "tlp-clear", "tlp-green", "tlp-amber", "tlp-red" ], - "Recommendation": "Maintain an up-to-date list of trusted and approved regions based\non organizational policies. Validate that child resources can only\nbe deployed to locations included in this list.\n", + "Recommendation": "Maintain an up-to-date list of trusted and approved regions based on organizational policies. Validate that child resources can only be deployed to locations included in this list. ", "SectionThreatMappings": [ { "ReferenceId": "CCC", @@ -6194,20 +4197,20 @@ }, { "Id": "CCC.Core.CN08.AR01", - "Description": "When data is created or modified, the data MUST have a complete\nand recoverable duplicate that is stored in a physically separate\ndata center.", + "Description": "When data is created or modified, the data MUST have a complete and recoverable duplicate that is stored in a physically separate data center.", "Attributes": [ { "FamilyName": "Data", - "FamilyDescription": "The Data control family ensures the confidentiality, integrity,\navailability, and sovereignty of data across its lifecycle.\nThese controls govern how data is transmitted, stored,\nreplicated, and protected from unauthorized access, tampering,\nor exposure beyond defined trust perimeters.\n", + "FamilyDescription": "The Data control family ensures the confidentiality, integrity, availability, and sovereignty of data across its lifecycle. These controls govern how data is transmitted, stored, replicated, and protected from unauthorized access, tampering, or exposure beyond defined trust perimeters. ", "Section": "CCC.Core.CN08 Replicate Data to Multiple Locations", "SubSection": "", - "SubSectionObjective": "Ensure that data is replicated across multiple physical locations to\nprotect against data loss due to hardware failures, natural disasters,\nor other catastrophic events.", + "SubSectionObjective": "Ensure that data is replicated across multiple physical locations to protect against data loss due to hardware failures, natural disasters, or other catastrophic events.", "Applicability": [ "tlp-green", "tlp-amber", "tlp-red" ], - "Recommendation": "Implement automated data replication processes to ensure that\ndata is consistently duplicated in another region or availability\nzone. Regularly test data recovery from the replicated location to\nensure integrity and availability.\n", + "Recommendation": "Implement automated data replication processes to ensure that data is consistently duplicated in another region or availability zone. Regularly test data recovery from the replicated location to ensure integrity and availability. ", "SectionThreatMappings": [ { "ReferenceId": "CCC", @@ -6249,14 +4252,14 @@ }, { "Id": "CCC.Core.CN08.AR02", - "Description": "When data is replicated into a second location, the service MUST\nbe able to accurately represent the replication locations,\nreplication status, and data synchronization status.", + "Description": "When data is replicated into a second location, the service MUST be able to accurately represent the replication locations, replication status, and data synchronization status.", "Attributes": [ { "FamilyName": "Data", - "FamilyDescription": "The Data control family ensures the confidentiality, integrity,\navailability, and sovereignty of data across its lifecycle.\nThese controls govern how data is transmitted, stored,\nreplicated, and protected from unauthorized access, tampering,\nor exposure beyond defined trust perimeters.\n", + "FamilyDescription": "The Data control family ensures the confidentiality, integrity, availability, and sovereignty of data across its lifecycle. These controls govern how data is transmitted, stored, replicated, and protected from unauthorized access, tampering, or exposure beyond defined trust perimeters. ", "Section": "CCC.Core.CN08 Replicate Data to Multiple Locations", "SubSection": "", - "SubSectionObjective": "Ensure that data is replicated across multiple physical locations to\nprotect against data loss due to hardware failures, natural disasters,\nor other catastrophic events.", + "SubSectionObjective": "Ensure that data is replicated across multiple physical locations to protect against data loss due to hardware failures, natural disasters, or other catastrophic events.", "Applicability": [ "tlp-green", "tlp-amber", @@ -6302,14 +4305,14 @@ }, { "Id": "CCC.Core.CN09.AR01", - "Description": "When the service is operational, its logs and any child resource\nlogs MUST NOT be accessible from the resource they record access\nto.", + "Description": "When the service is operational, its logs and any child resource logs MUST NOT be accessible from the resource they record access to.", "Attributes": [ { "FamilyName": "Data", - "FamilyDescription": "The Data control family ensures the confidentiality, integrity,\navailability, and sovereignty of data across its lifecycle.\nThese controls govern how data is transmitted, stored,\nreplicated, and protected from unauthorized access, tampering,\nor exposure beyond defined trust perimeters.\n", + "FamilyDescription": "The Data control family ensures the confidentiality, integrity, availability, and sovereignty of data across its lifecycle. These controls govern how data is transmitted, stored, replicated, and protected from unauthorized access, tampering, or exposure beyond defined trust perimeters. ", "Section": "CCC.Core.CN09 Ensure Integrity of Access Logs", "SubSection": "", - "SubSectionObjective": "Ensure that access logs are always recorded to an external location\nthat cannot be manipulated from the context of the service(s) it\ncontains logs for.", + "SubSectionObjective": "Ensure that access logs are always recorded to an external location that cannot be manipulated from the context of the service(s) it contains logs for.", "Applicability": [ "tlp-clear", "tlp-green", @@ -6360,21 +4363,21 @@ }, { "Id": "CCC.Core.CN09.AR02", - "Description": "When the service is operational, disabling the logs for the service\nor its child resources MUST NOT be possible without also disabling\nthe corresponding resource.", + "Description": "When the service is operational, disabling the logs for the service or its child resources MUST NOT be possible without also disabling the corresponding resource.", "Attributes": [ { "FamilyName": "Data", - "FamilyDescription": "The Data control family ensures the confidentiality, integrity,\navailability, and sovereignty of data across its lifecycle.\nThese controls govern how data is transmitted, stored,\nreplicated, and protected from unauthorized access, tampering,\nor exposure beyond defined trust perimeters.\n", + "FamilyDescription": "The Data control family ensures the confidentiality, integrity, availability, and sovereignty of data across its lifecycle. These controls govern how data is transmitted, stored, replicated, and protected from unauthorized access, tampering, or exposure beyond defined trust perimeters. ", "Section": "CCC.Core.CN09 Ensure Integrity of Access Logs", "SubSection": "", - "SubSectionObjective": "Ensure that access logs are always recorded to an external location\nthat cannot be manipulated from the context of the service(s) it\ncontains logs for.", + "SubSectionObjective": "Ensure that access logs are always recorded to an external location that cannot be manipulated from the context of the service(s) it contains logs for.", "Applicability": [ "tlp-clear", "tlp-green", "tlp-amber", "tlp-red" ], - "Recommendation": "No normal business operations should disable\nlogs, as this could indicate an attempt to cover up unauthorized\naccess. Ensure that logging mechanisms are tightly integrated with\nservice operations, so that logging cannot be disabled without\nstopping the service itself.\n", + "Recommendation": "No normal business operations should disable logs, as this could indicate an attempt to cover up unauthorized access. Ensure that logging mechanisms are tightly integrated with service operations, so that logging cannot be disabled without stopping the service itself. ", "SectionThreatMappings": [ { "ReferenceId": "CCC", @@ -6420,19 +4423,19 @@ }, { "Id": "CCC.Core.CN09.AR03", - "Description": "When the service is operational, any attempt to redirect logs for\nthe service or its child resources MUST NOT be possible without\nhalting operation of the corresponding resource and publishing\ncorresponding events to monitored channels.", + "Description": "When the service is operational, any attempt to redirect logs for the service or its child resources MUST NOT be possible without halting operation of the corresponding resource and publishing corresponding events to monitored channels.", "Attributes": [ { "FamilyName": "Data", - "FamilyDescription": "The Data control family ensures the confidentiality, integrity,\navailability, and sovereignty of data across its lifecycle.\nThese controls govern how data is transmitted, stored,\nreplicated, and protected from unauthorized access, tampering,\nor exposure beyond defined trust perimeters.\n", + "FamilyDescription": "The Data control family ensures the confidentiality, integrity, availability, and sovereignty of data across its lifecycle. These controls govern how data is transmitted, stored, replicated, and protected from unauthorized access, tampering, or exposure beyond defined trust perimeters. ", "Section": "CCC.Core.CN09 Ensure Integrity of Access Logs", "SubSection": "", - "SubSectionObjective": "Ensure that access logs are always recorded to an external location\nthat cannot be manipulated from the context of the service(s) it\ncontains logs for.", + "SubSectionObjective": "Ensure that access logs are always recorded to an external location that cannot be manipulated from the context of the service(s) it contains logs for.", "Applicability": [ "tlp-amber", "tlp-red" ], - "Recommendation": "No normal business operations should result in the redirection of\nlogs, as this could indicate an attempt to cover up unauthorized\naccess. Ensure that logging configurations are immutable during\nservice operation so that any changes require stopping the service\nand publishing corresponding events to monitored channels.\n", + "Recommendation": "No normal business operations should result in the redirection of logs, as this could indicate an attempt to cover up unauthorized access. Ensure that logging configurations are immutable during service operation so that any changes require stopping the service and publishing corresponding events to monitored channels. ", "SectionThreatMappings": [ { "ReferenceId": "CCC", @@ -6479,14 +4482,14 @@ }, { "Id": "CCC.Core.CN10.AR01", - "Description": "When data is replicated, the service MUST ensure that replication\nonly occurs to destinations that are explicitly included within\nthe defined trust perimeter.", + "Description": "When data is replicated, the service MUST ensure that replication only occurs to destinations that are explicitly included within the defined trust perimeter.", "Attributes": [ { "FamilyName": "Data", - "FamilyDescription": "The Data control family ensures the confidentiality, integrity,\navailability, and sovereignty of data across its lifecycle.\nThese controls govern how data is transmitted, stored,\nreplicated, and protected from unauthorized access, tampering,\nor exposure beyond defined trust perimeters.\n", + "FamilyDescription": "The Data control family ensures the confidentiality, integrity, availability, and sovereignty of data across its lifecycle. These controls govern how data is transmitted, stored, replicated, and protected from unauthorized access, tampering, or exposure beyond defined trust perimeters. ", "Section": "CCC.Core.CN10 Restrict Data Replication to Trust Perimeter", "SubSection": "", - "SubSectionObjective": "Ensure that data is only replicated on infrastructure in locations\nthat are explicitly included within a defined trust perimeter.", + "SubSectionObjective": "Ensure that data is only replicated on infrastructure in locations that are explicitly included within a defined trust perimeter.", "Applicability": [ "tlp-green", "tlp-amber", @@ -6535,14 +4538,14 @@ }, { "Id": "CCC.Core.CN02.AR01", - "Description": "When data is stored, it MUST be encrypted using the latest\nindustry-standard encryption methods.", + "Description": "When data is stored, it MUST be encrypted using the latest industry-standard encryption methods.", "Attributes": [ { "FamilyName": "Data", - "FamilyDescription": "The Data control family ensures the confidentiality, integrity,\navailability, and sovereignty of data across its lifecycle.\nThese controls govern how data is transmitted, stored,\nreplicated, and protected from unauthorized access, tampering,\nor exposure beyond defined trust perimeters.\n", + "FamilyDescription": "The Data control family ensures the confidentiality, integrity, availability, and sovereignty of data across its lifecycle. These controls govern how data is transmitted, stored, replicated, and protected from unauthorized access, tampering, or exposure beyond defined trust perimeters. ", "Section": "CCC.Core.CN02 Encrypt Data for Storage", "SubSection": "", - "SubSectionObjective": "Ensure that all data stored is encrypted at rest using strong\nencryption algorithms.", + "SubSectionObjective": "Ensure that all data stored is encrypted at rest using strong encryption algorithms.", "Applicability": [ "tlp-green", "tlp-amber", @@ -6596,14 +4599,14 @@ }, { "Id": "CCC.Core.CN11.AR01", - "Description": "When encryption keys are used, the service MUST verify that\nall encryption keys use the latest industry-standard cryptographic\nalgorithms.", + "Description": "When encryption keys are used, the service MUST verify that all encryption keys use the latest industry-standard cryptographic algorithms.", "Attributes": [ { "FamilyName": "Data", - "FamilyDescription": "The Data control family ensures the confidentiality, integrity,\navailability, and sovereignty of data across its lifecycle.\nThese controls govern how data is transmitted, stored,\nreplicated, and protected from unauthorized access, tampering,\nor exposure beyond defined trust perimeters.\n", + "FamilyDescription": "The Data control family ensures the confidentiality, integrity, availability, and sovereignty of data across its lifecycle. These controls govern how data is transmitted, stored, replicated, and protected from unauthorized access, tampering, or exposure beyond defined trust perimeters. ", "Section": "CCC.Core.CN11 Protect Encryption Keys", "SubSection": "", - "SubSectionObjective": "Ensure that encryption keys are managed securely by enforcing\nthe use of approved algorithms, regular key rotation, and\ncustomer-managed encryption keys (CMEKs).", + "SubSectionObjective": "Ensure that encryption keys are managed securely by enforcing the use of approved algorithms, regular key rotation, and customer-managed encryption keys (CMEKs).", "Applicability": [ "tlp-amber", "tlp-red" @@ -6664,14 +4667,14 @@ }, { "Id": "CCC.Core.CN11.AR02", - "Description": "When encryption keys are used, the service MUST rotate active keys\nwithin 180 days of issuance.", + "Description": "When encryption keys are used, the service MUST rotate active keys within 180 days of issuance.", "Attributes": [ { "FamilyName": "Data", - "FamilyDescription": "The Data control family ensures the confidentiality, integrity,\navailability, and sovereignty of data across its lifecycle.\nThese controls govern how data is transmitted, stored,\nreplicated, and protected from unauthorized access, tampering,\nor exposure beyond defined trust perimeters.\n", + "FamilyDescription": "The Data control family ensures the confidentiality, integrity, availability, and sovereignty of data across its lifecycle. These controls govern how data is transmitted, stored, replicated, and protected from unauthorized access, tampering, or exposure beyond defined trust perimeters. ", "Section": "CCC.Core.CN11 Protect Encryption Keys", "SubSection": "", - "SubSectionObjective": "Ensure that encryption keys are managed securely by enforcing\nthe use of approved algorithms, regular key rotation, and\ncustomer-managed encryption keys (CMEKs).", + "SubSectionObjective": "Ensure that encryption keys are managed securely by enforcing the use of approved algorithms, regular key rotation, and customer-managed encryption keys (CMEKs).", "Applicability": [ "tlp-amber" ], @@ -6723,14 +4726,14 @@ }, { "Id": "CCC.Core.CN11.AR03", - "Description": "When encrypting data, the service MUST verify that\ncustomer-managed encryption keys (CMEKs) are used.", + "Description": "When encrypting data, the service MUST verify that customer-managed encryption keys (CMEKs) are used.", "Attributes": [ { "FamilyName": "Data", - "FamilyDescription": "The Data control family ensures the confidentiality, integrity,\navailability, and sovereignty of data across its lifecycle.\nThese controls govern how data is transmitted, stored,\nreplicated, and protected from unauthorized access, tampering,\nor exposure beyond defined trust perimeters.\n", + "FamilyDescription": "The Data control family ensures the confidentiality, integrity, availability, and sovereignty of data across its lifecycle. These controls govern how data is transmitted, stored, replicated, and protected from unauthorized access, tampering, or exposure beyond defined trust perimeters. ", "Section": "", "SubSection": "CCC.Core.CN11 Protect Encryption Keys", - "SubSectionObjective": "Ensure that encryption keys are managed securely by enforcing\nthe use of approved algorithms, regular key rotation, and\ncustomer-managed encryption keys (CMEKs).", + "SubSectionObjective": "Ensure that encryption keys are managed securely by enforcing the use of approved algorithms, regular key rotation, and customer-managed encryption keys (CMEKs).", "Applicability": [ "tlp-amber", "tlp-red" @@ -6786,14 +4789,14 @@ }, { "Id": "CCC.Core.CN11.AR04", - "Description": "When encryption keys are accessed, the service MUST verify that\naccess to encryption keys is restricted to authorized personnel\nand services, following the principle of least privilege.", + "Description": "When encryption keys are accessed, the service MUST verify that access to encryption keys is restricted to authorized personnel and services, following the principle of least privilege.", "Attributes": [ { "FamilyName": "Data", - "FamilyDescription": "The Data control family ensures the confidentiality, integrity,\navailability, and sovereignty of data across its lifecycle.\nThese controls govern how data is transmitted, stored,\nreplicated, and protected from unauthorized access, tampering,\nor exposure beyond defined trust perimeters.\n", + "FamilyDescription": "The Data control family ensures the confidentiality, integrity, availability, and sovereignty of data across its lifecycle. These controls govern how data is transmitted, stored, replicated, and protected from unauthorized access, tampering, or exposure beyond defined trust perimeters. ", "Section": "CCC.Core.CN11 Protect Encryption Keys", "SubSection": "", - "SubSectionObjective": "Ensure that encryption keys are managed securely by enforcing\nthe use of approved algorithms, regular key rotation, and\ncustomer-managed encryption keys (CMEKs).", + "SubSectionObjective": "Ensure that encryption keys are managed securely by enforcing the use of approved algorithms, regular key rotation, and customer-managed encryption keys (CMEKs).", "Applicability": [ "tlp-clear", "tlp-green", @@ -6855,14 +4858,14 @@ }, { "Id": "CCC.Core.CN11.AR05", - "Description": "When encryption keys are used, the service MUST rotate active keys\nwithin 365 days of issuance.", + "Description": "When encryption keys are used, the service MUST rotate active keys within 365 days of issuance.", "Attributes": [ { "FamilyName": "Data", - "FamilyDescription": "The Data control family ensures the confidentiality, integrity,\navailability, and sovereignty of data across its lifecycle.\nThese controls govern how data is transmitted, stored,\nreplicated, and protected from unauthorized access, tampering,\nor exposure beyond defined trust perimeters.\n", + "FamilyDescription": "The Data control family ensures the confidentiality, integrity, availability, and sovereignty of data across its lifecycle. These controls govern how data is transmitted, stored, replicated, and protected from unauthorized access, tampering, or exposure beyond defined trust perimeters. ", "Section": "CCC.Core.CN11 Protect Encryption Keys", "SubSection": "", - "SubSectionObjective": "Ensure that encryption keys are managed securely by enforcing\nthe use of approved algorithms, regular key rotation, and\ncustomer-managed encryption keys (CMEKs).", + "SubSectionObjective": "Ensure that encryption keys are managed securely by enforcing the use of approved algorithms, regular key rotation, and customer-managed encryption keys (CMEKs).", "Applicability": [ "tlp-clear", "tlp-green" @@ -6919,14 +4922,14 @@ }, { "Id": "CCC.Core.CN11.AR06", - "Description": "When encryption keys are used, the service MUST rotate active keys\nwithin 90 days of issuance.", + "Description": "When encryption keys are used, the service MUST rotate active keys within 90 days of issuance.", "Attributes": [ { "FamilyName": "Data", - "FamilyDescription": "The Data control family ensures the confidentiality, integrity,\navailability, and sovereignty of data across its lifecycle.\nThese controls govern how data is transmitted, stored,\nreplicated, and protected from unauthorized access, tampering,\nor exposure beyond defined trust perimeters.\n", + "FamilyDescription": "The Data control family ensures the confidentiality, integrity, availability, and sovereignty of data across its lifecycle. These controls govern how data is transmitted, stored, replicated, and protected from unauthorized access, tampering, or exposure beyond defined trust perimeters. ", "Section": "CCC.Core.CN11 Protect Encryption Keys", "SubSection": "", - "SubSectionObjective": "Ensure that encryption keys are managed securely by enforcing\nthe use of approved algorithms, regular key rotation, and\ncustomer-managed encryption keys (CMEKs).", + "SubSectionObjective": "Ensure that encryption keys are managed securely by enforcing the use of approved algorithms, regular key rotation, and customer-managed encryption keys (CMEKs).", "Applicability": [ "tlp-red" ], @@ -6976,21 +4979,21 @@ }, { "Id": "CCC.Core.CN14.AR01", - "Description": "When backups are created for disaster recovery purposes, the\nstorage mechanism MUST NOT allow modification or deletion\nwithin 30 days of creation.", + "Description": "When backups are created for disaster recovery purposes, the storage mechanism MUST NOT allow modification or deletion within 30 days of creation.", "Attributes": [ { "FamilyName": "Data", - "FamilyDescription": "The Data control family ensures the confidentiality, integrity,\navailability, and sovereignty of data across its lifecycle.\nThese controls govern how data is transmitted, stored,\nreplicated, and protected from unauthorized access, tampering,\nor exposure beyond defined trust perimeters.\n", + "FamilyDescription": "The Data control family ensures the confidentiality, integrity, availability, and sovereignty of data across its lifecycle. These controls govern how data is transmitted, stored, replicated, and protected from unauthorized access, tampering, or exposure beyond defined trust perimeters. ", "Section": "CCC.Core.CN14 Maintain Recent Backups", "SubSection": "", - "SubSectionObjective": "Ensure that all backups used for disaster recovery are recent and\nsubject to a retention policy that limits deletion.", + "SubSectionObjective": "Ensure that all backups used for disaster recovery are recent and subject to a retention policy that limits deletion.", "Applicability": [ "tlp-clear", "tlp-green", "tlp-amber", "tlp-red" ], - "Recommendation": "Use immutable storage solutions where possible. Implement backup\nretention policies that enforce a minimum retention period of 30\ndays.\n", + "Recommendation": "Use immutable storage solutions where possible. Implement backup retention policies that enforce a minimum retention period of 30 days. ", "SectionThreatMappings": [ { "ReferenceId": "CCC", @@ -7009,20 +5012,20 @@ }, { "Id": "CCC.Core.CN14.AR02", - "Description": "When backups are created for disaster recovery purposes, the\nmost recent backup MUST have a creation date within the past\n30 days.", + "Description": "When backups are created for disaster recovery purposes, the most recent backup MUST have a creation date within the past 30 days.", "Attributes": [ { "FamilyName": "Data", - "FamilyDescription": "The Data control family ensures the confidentiality, integrity,\navailability, and sovereignty of data across its lifecycle.\nThese controls govern how data is transmitted, stored,\nreplicated, and protected from unauthorized access, tampering,\nor exposure beyond defined trust perimeters.\n", + "FamilyDescription": "The Data control family ensures the confidentiality, integrity, availability, and sovereignty of data across its lifecycle. These controls govern how data is transmitted, stored, replicated, and protected from unauthorized access, tampering, or exposure beyond defined trust perimeters. ", "Section": "CCC.Core.CN14 Maintain Recent Backups", "SubSection": "", - "SubSectionObjective": "Ensure that all backups used for disaster recovery are recent and\nsubject to a retention policy that limits deletion.", + "SubSectionObjective": "Ensure that all backups used for disaster recovery are recent and subject to a retention policy that limits deletion.", "Applicability": [ "tlp-clear", "tlp-green", "tlp-amber" ], - "Recommendation": "Implement automated backup processes to ensure that backups are\ncreated regularly. Monitor backup schedules and verify that the\nmost recent backup creation date is within the last 30 days.\n", + "Recommendation": "Implement automated backup processes to ensure that backups are created regularly. Monitor backup schedules and verify that the most recent backup creation date is within the last 30 days. ", "SectionThreatMappings": [ { "ReferenceId": "CCC", @@ -7041,18 +5044,18 @@ }, { "Id": "CCC.Core.CN14.AR02", - "Description": "When backups are created for disaster recovery purposes, the\nmost recent backup MUST have a creation date within the past\n14 days.", + "Description": "When backups are created for disaster recovery purposes, the most recent backup MUST have a creation date within the past 14 days.", "Attributes": [ { "FamilyName": "Data", - "FamilyDescription": "The Data control family ensures the confidentiality, integrity,\navailability, and sovereignty of data across its lifecycle.\nThese controls govern how data is transmitted, stored,\nreplicated, and protected from unauthorized access, tampering,\nor exposure beyond defined trust perimeters.\n", + "FamilyDescription": "The Data control family ensures the confidentiality, integrity, availability, and sovereignty of data across its lifecycle. These controls govern how data is transmitted, stored, replicated, and protected from unauthorized access, tampering, or exposure beyond defined trust perimeters. ", "Section": "CCC.Core.CN14 Maintain Recent Backups", "SubSection": "", - "SubSectionObjective": "Ensure that all backups used for disaster recovery are recent and\nsubject to a retention policy that limits deletion.", + "SubSectionObjective": "Ensure that all backups used for disaster recovery are recent and subject to a retention policy that limits deletion.", "Applicability": [ "tlp-red" ], - "Recommendation": "Implement automated backup processes to ensure that backups are\ncreated regularly. Monitor backup schedules and verify that the\nmost recent backup creation date is within the last 14 days.\n", + "Recommendation": "Implement automated backup processes to ensure that backups are created regularly. Monitor backup schedules and verify that the most recent backup creation date is within the last 14 days. ", "SectionThreatMappings": [ { "ReferenceId": "CCC", @@ -7071,14 +5074,14 @@ }, { "Id": "CCC.Core.CN03.AR01", - "Description": "When an entity attempts to modify the service through a user\ninterface, the authentication process MUST require multiple\nidentifying factors for authentication.", + "Description": "When an entity attempts to modify the service through a user interface, the authentication process MUST require multiple identifying factors for authentication.", "Attributes": [ { "FamilyName": "Identity and Access Management", - "FamilyDescription": "The Identity and Access Management control family ensures\nthat only trusted and authenticated entities can access\nresources. These controls establish strong authentication,\nenforce multi-factor verification, and restrict access to\napproved sources to prevent unauthorized use or data exfiltration.\n", + "FamilyDescription": "The Identity and Access Management control family ensures that only trusted and authenticated entities can access resources. These controls establish strong authentication, enforce multi-factor verification, and restrict access to approved sources to prevent unauthorized use or data exfiltration. ", "Section": "CCC.Core.CN03 Implement Multi-factor Authentication (MFA) for Access", "SubSection": "", - "SubSectionObjective": "Ensure that all sensitive activities require two or more identity\nfactors during authentication to prevent unauthorized access.", + "SubSectionObjective": "Ensure that all sensitive activities require two or more identity factors during authentication to prevent unauthorized access.", "Applicability": [ "tlp-clear", "tlp-green", @@ -7139,14 +5142,14 @@ }, { "Id": "CCC.Core.CN03.AR02", - "Description": "When an entity attempts to modify the service through an API\nendpoint, the authentication process MUST require a credential\nsuch as an API key or token AND originate from within the trust\nperimeter.", + "Description": "When an entity attempts to modify the service through an API endpoint, the authentication process MUST require a credential such as an API key or token AND originate from within the trust perimeter.", "Attributes": [ { "FamilyName": "Identity and Access Management", - "FamilyDescription": "The Identity and Access Management control family ensures\nthat only trusted and authenticated entities can access\nresources. These controls establish strong authentication,\nenforce multi-factor verification, and restrict access to\napproved sources to prevent unauthorized use or data exfiltration.\n", + "FamilyDescription": "The Identity and Access Management control family ensures that only trusted and authenticated entities can access resources. These controls establish strong authentication, enforce multi-factor verification, and restrict access to approved sources to prevent unauthorized use or data exfiltration. ", "Section": "CCC.Core.CN03 Implement Multi-factor Authentication (MFA) for Access", "SubSection": "", - "SubSectionObjective": "Ensure that all sensitive activities require two or more identity\nfactors during authentication to prevent unauthorized access.", + "SubSectionObjective": "Ensure that all sensitive activities require two or more identity factors during authentication to prevent unauthorized access.", "Applicability": [ "tlp-clear", "tlp-green", @@ -7206,14 +5209,14 @@ }, { "Id": "CCC.Core.CN03.AR03", - "Description": "When an entity attempts to view information on the service through\na user interface, the authentication process MUST require multiple\nidentifying factors from the user.", + "Description": "When an entity attempts to view information on the service through a user interface, the authentication process MUST require multiple identifying factors from the user.", "Attributes": [ { "FamilyName": "Identity and Access Management", - "FamilyDescription": "The Identity and Access Management control family ensures\nthat only trusted and authenticated entities can access\nresources. These controls establish strong authentication,\nenforce multi-factor verification, and restrict access to\napproved sources to prevent unauthorized use or data exfiltration.\n", + "FamilyDescription": "The Identity and Access Management control family ensures that only trusted and authenticated entities can access resources. These controls establish strong authentication, enforce multi-factor verification, and restrict access to approved sources to prevent unauthorized use or data exfiltration. ", "Section": "CCC.Core.CN03 Implement Multi-factor Authentication (MFA) for Access", "SubSection": "", - "SubSectionObjective": "Ensure that all sensitive activities require two or more identity\nfactors during authentication to prevent unauthorized access.", + "SubSectionObjective": "Ensure that all sensitive activities require two or more identity factors during authentication to prevent unauthorized access.", "Applicability": [ "tlp-amber", "tlp-red" @@ -7271,14 +5274,14 @@ }, { "Id": "CCC.Core.CN03.AR04", - "Description": "When an entity attempts to view information on the service through\nan API endpoint, the authentication process MUST require a\ncredential such as an API key or token AND originate from within\nthe trust perimeter.", + "Description": "When an entity attempts to view information on the service through an API endpoint, the authentication process MUST require a credential such as an API key or token AND originate from within the trust perimeter.", "Attributes": [ { "FamilyName": "Identity and Access Management", - "FamilyDescription": "The Identity and Access Management control family ensures\nthat only trusted and authenticated entities can access\nresources. These controls establish strong authentication,\nenforce multi-factor verification, and restrict access to\napproved sources to prevent unauthorized use or data exfiltration.\n", + "FamilyDescription": "The Identity and Access Management control family ensures that only trusted and authenticated entities can access resources. These controls establish strong authentication, enforce multi-factor verification, and restrict access to approved sources to prevent unauthorized use or data exfiltration. ", "Section": "CCC.Core.CN03 Implement Multi-factor Authentication (MFA) for Access", "SubSection": "", - "SubSectionObjective": "Ensure that all sensitive activities require two or more identity\nfactors during authentication to prevent unauthorized access.", + "SubSectionObjective": "Ensure that all sensitive activities require two or more identity factors during authentication to prevent unauthorized access.", "Applicability": [ "tlp-amber", "tlp-red" @@ -7336,14 +5339,14 @@ }, { "Id": "CCC.Core.CN05.AR01", - "Description": "When an attempt is made to modify data on the service or a child\nresource, the service MUST block requests from unauthorized\nentities.", + "Description": "When an attempt is made to modify data on the service or a child resource, the service MUST block requests from unauthorized entities.", "Attributes": [ { "FamilyName": "Identity and Access Management", - "FamilyDescription": "The Identity and Access Management control family ensures\nthat only trusted and authenticated entities can access\nresources. These controls establish strong authentication,\nenforce multi-factor verification, and restrict access to\napproved sources to prevent unauthorized use or data exfiltration.\n", + "FamilyDescription": "The Identity and Access Management control family ensures that only trusted and authenticated entities can access resources. These controls establish strong authentication, enforce multi-factor verification, and restrict access to approved sources to prevent unauthorized use or data exfiltration. ", "Section": "CCC.Core.CN05 Prevent Access from Untrusted Entities", "SubSection": "", - "SubSectionObjective": "Ensure that secure access controls enforce the principle of least\nprivilege to restrict access to authorized entities from explicitly\ntrusted sources only.", + "SubSectionObjective": "Ensure that secure access controls enforce the principle of least privilege to restrict access to authorized entities from explicitly trusted sources only.", "Applicability": [ "tlp-clear", "tlp-green", @@ -7420,14 +5423,14 @@ }, { "Id": "CCC.Core.CN05.AR02", - "Description": "When administrative access or configuration change is attempted on\nthe service or a child resource, the service MUST refuse requests\nfrom unauthorized entities.", + "Description": "When administrative access or configuration change is attempted on the service or a child resource, the service MUST refuse requests from unauthorized entities.", "Attributes": [ { "FamilyName": "Identity and Access Management", - "FamilyDescription": "The Identity and Access Management control family ensures\nthat only trusted and authenticated entities can access\nresources. These controls establish strong authentication,\nenforce multi-factor verification, and restrict access to\napproved sources to prevent unauthorized use or data exfiltration.\n", + "FamilyDescription": "The Identity and Access Management control family ensures that only trusted and authenticated entities can access resources. These controls establish strong authentication, enforce multi-factor verification, and restrict access to approved sources to prevent unauthorized use or data exfiltration. ", "Section": "CCC.Core.CN05 Prevent Access from Untrusted Entities", "SubSection": "", - "SubSectionObjective": "Ensure that secure access controls enforce the principle of least\nprivilege to restrict access to authorized entities from explicitly\ntrusted sources only.", + "SubSectionObjective": "Ensure that secure access controls enforce the principle of least privilege to restrict access to authorized entities from explicitly trusted sources only.", "Applicability": [ "tlp-clear", "tlp-green", @@ -7512,14 +5515,14 @@ }, { "Id": "CCC.Core.CN05.AR03", - "Description": "When administrative access or configuration change is attempted on\nthe service or a child resource in a multi-tenant environment, the\nservice MUST refuse requests across tenant boundaries unless the\norigin is explicitly included in a pre-approved allowlist.", + "Description": "When administrative access or configuration change is attempted on the service or a child resource in a multi-tenant environment, the service MUST refuse requests across tenant boundaries unless the origin is explicitly included in a pre-approved allowlist.", "Attributes": [ { "FamilyName": "Identity and Access Management", - "FamilyDescription": "The Identity and Access Management control family ensures\nthat only trusted and authenticated entities can access\nresources. These controls establish strong authentication,\nenforce multi-factor verification, and restrict access to\napproved sources to prevent unauthorized use or data exfiltration.\n", + "FamilyDescription": "The Identity and Access Management control family ensures that only trusted and authenticated entities can access resources. These controls establish strong authentication, enforce multi-factor verification, and restrict access to approved sources to prevent unauthorized use or data exfiltration. ", "Section": "CCC.Core.CN05 Prevent Access from Untrusted Entities", "SubSection": "", - "SubSectionObjective": "Ensure that secure access controls enforce the principle of least\nprivilege to restrict access to authorized entities from explicitly\ntrusted sources only.", + "SubSectionObjective": "Ensure that secure access controls enforce the principle of least privilege to restrict access to authorized entities from explicitly trusted sources only.", "Applicability": [ "tlp-clear", "tlp-green", @@ -7594,14 +5597,14 @@ }, { "Id": "CCC.Core.CN05.AR04", - "Description": "When data is requested from outside the trust perimeter, the\nservice MUST refuse requests from unauthorized entities.", + "Description": "When data is requested from outside the trust perimeter, the service MUST refuse requests from unauthorized entities.", "Attributes": [ { "FamilyName": "Identity and Access Management", - "FamilyDescription": "The Identity and Access Management control family ensures\nthat only trusted and authenticated entities can access\nresources. These controls establish strong authentication,\nenforce multi-factor verification, and restrict access to\napproved sources to prevent unauthorized use or data exfiltration.\n", + "FamilyDescription": "The Identity and Access Management control family ensures that only trusted and authenticated entities can access resources. These controls establish strong authentication, enforce multi-factor verification, and restrict access to approved sources to prevent unauthorized use or data exfiltration. ", "Section": "", "SubSection": "CCC.Core.CN05 Prevent Access from Untrusted Entities", - "SubSectionObjective": "Ensure that secure access controls enforce the principle of least\nprivilege to restrict access to authorized entities from explicitly\ntrusted sources only.", + "SubSectionObjective": "Ensure that secure access controls enforce the principle of least privilege to restrict access to authorized entities from explicitly trusted sources only.", "Applicability": [ "tlp-amber", "tlp-red" @@ -7688,14 +5691,14 @@ }, { "Id": "CCC.Core.CN05.AR05", - "Description": "When any request is made from outside the trust perimeter,\nthe service MUST NOT provide any response that may indicate the\nservice exists.", + "Description": "When any request is made from outside the trust perimeter, the service MUST NOT provide any response that may indicate the service exists.", "Attributes": [ { "FamilyName": "Identity and Access Management", - "FamilyDescription": "The Identity and Access Management control family ensures\nthat only trusted and authenticated entities can access\nresources. These controls establish strong authentication,\nenforce multi-factor verification, and restrict access to\napproved sources to prevent unauthorized use or data exfiltration.\n", + "FamilyDescription": "The Identity and Access Management control family ensures that only trusted and authenticated entities can access resources. These controls establish strong authentication, enforce multi-factor verification, and restrict access to approved sources to prevent unauthorized use or data exfiltration. ", "Section": "CCC.Core.CN05 Prevent Access from Untrusted Entities", "SubSection": "", - "SubSectionObjective": "Ensure that secure access controls enforce the principle of least\nprivilege to restrict access to authorized entities from explicitly\ntrusted sources only.", + "SubSectionObjective": "Ensure that secure access controls enforce the principle of least privilege to restrict access to authorized entities from explicitly trusted sources only.", "Applicability": [ "tlp-red" ], @@ -7774,14 +5777,14 @@ }, { "Id": "CCC.Core.CN05.AR06", - "Description": "When any request is made to the service or a child resource, the\nservice MUST refuse requests from unauthorized entities.", + "Description": "When any request is made to the service or a child resource, the service MUST refuse requests from unauthorized entities.", "Attributes": [ { "FamilyName": "Identity and Access Management", - "FamilyDescription": "The Identity and Access Management control family ensures\nthat only trusted and authenticated entities can access\nresources. These controls establish strong authentication,\nenforce multi-factor verification, and restrict access to\napproved sources to prevent unauthorized use or data exfiltration.\n", + "FamilyDescription": "The Identity and Access Management control family ensures that only trusted and authenticated entities can access resources. These controls establish strong authentication, enforce multi-factor verification, and restrict access to approved sources to prevent unauthorized use or data exfiltration. ", "Section": "CCC.Core.CN05 Prevent Access from Untrusted Entities", "SubSection": "", - "SubSectionObjective": "Ensure that secure access controls enforce the principle of least\nprivilege to restrict access to authorized entities from explicitly\ntrusted sources only.", + "SubSectionObjective": "Ensure that secure access controls enforce the principle of least privilege to restrict access to authorized entities from explicitly trusted sources only.", "Applicability": [ "tlp-green", "tlp-amber", @@ -7850,14 +5853,14 @@ }, { "Id": "CCC.Core.CN04.AR01", - "Description": "When administrative access or configuration change is attempted on\nthe service or a child resource, the service MUST log the client\nidentity, time, and result of the attempt.", + "Description": "When administrative access or configuration change is attempted on the service or a child resource, the service MUST log the client identity, time, and result of the attempt.", "Attributes": [ { "FamilyName": "Logging & Monitoring", - "FamilyDescription": "The Logging & Monitoring control family ensures that access,\nchanges, and security-relevant events are captured, monitored,\nand alerted on in order to provide visibility, support\nincident response, and meet compliance requirements.\n", + "FamilyDescription": "The Logging & Monitoring control family ensures that access, changes, and security-relevant events are captured, monitored, and alerted on in order to provide visibility, support incident response, and meet compliance requirements. ", "Section": "CCC.Core.CN04 Log All Access and Changes", "SubSection": "", - "SubSectionObjective": "Ensure that all access attempts are logged to maintain a detailed\naudit trail for security and compliance purposes.", + "SubSectionObjective": "Ensure that all access attempts are logged to maintain a detailed audit trail for security and compliance purposes.", "Applicability": [ "tlp-clear", "tlp-green", @@ -7916,14 +5919,14 @@ }, { "Id": "CCC.Core.CN04.AR02", - "Description": "When any attempt is made to modify data on the service or a child\nresource, the service MUST log the client identity, time, and\nresult of the attempt.", + "Description": "When any attempt is made to modify data on the service or a child resource, the service MUST log the client identity, time, and result of the attempt.", "Attributes": [ { "FamilyName": "Logging & Monitoring", - "FamilyDescription": "The Logging & Monitoring control family ensures that access,\nchanges, and security-relevant events are captured, monitored,\nand alerted on in order to provide visibility, support\nincident response, and meet compliance requirements.\n", + "FamilyDescription": "The Logging & Monitoring control family ensures that access, changes, and security-relevant events are captured, monitored, and alerted on in order to provide visibility, support incident response, and meet compliance requirements. ", "Section": "CCC.Core.CN04 Log All Access and Changes", "SubSection": "", - "SubSectionObjective": "Ensure that all access attempts are logged to maintain a detailed\naudit trail for security and compliance purposes.", + "SubSectionObjective": "Ensure that all access attempts are logged to maintain a detailed audit trail for security and compliance purposes.", "Applicability": [ "tlp-amber", "tlp-red" @@ -7972,14 +5975,14 @@ }, { "Id": "CCC.Core.CN04.AR03", - "Description": "When any attempt is made to read data on the service or a child\nresource, the service MUST log the client identity, time, and\nresult of the attempt.", + "Description": "When any attempt is made to read data on the service or a child resource, the service MUST log the client identity, time, and result of the attempt.", "Attributes": [ { "FamilyName": "Logging & Monitoring", - "FamilyDescription": "The Logging & Monitoring control family ensures that access,\nchanges, and security-relevant events are captured, monitored,\nand alerted on in order to provide visibility, support\nincident response, and meet compliance requirements.\n", + "FamilyDescription": "The Logging & Monitoring control family ensures that access, changes, and security-relevant events are captured, monitored, and alerted on in order to provide visibility, support incident response, and meet compliance requirements. ", "Section": "CCC.Core.CN04 Log All Access and Changes", "SubSection": "", - "SubSectionObjective": "Ensure that all access attempts are logged to maintain a detailed\naudit trail for security and compliance purposes.", + "SubSectionObjective": "Ensure that all access attempts are logged to maintain a detailed audit trail for security and compliance purposes.", "Applicability": [ "tlp-red" ], @@ -8028,19 +6031,19 @@ }, { "Id": "CCC.Core.CN07.AR01", - "Description": "When enumeration activities are detected, the service MUST publish\nan event to a monitored channel which includes the client\nidentity, time, and nature of the activity.", + "Description": "When enumeration activities are detected, the service MUST publish an event to a monitored channel which includes the client identity, time, and nature of the activity.", "Attributes": [ { "FamilyName": "Logging & Monitoring", - "FamilyDescription": "The Logging & Monitoring control family ensures that access,\nchanges, and security-relevant events are captured, monitored,\nand alerted on in order to provide visibility, support\nincident response, and meet compliance requirements.\n", + "FamilyDescription": "The Logging & Monitoring control family ensures that access, changes, and security-relevant events are captured, monitored, and alerted on in order to provide visibility, support incident response, and meet compliance requirements. ", "Section": "CCC.Core.CN07 Alert on Unusual Enumeration Activity", "SubSection": "", - "SubSectionObjective": "Ensure that logs and associated alerts are generated when\nunusual enumeration activity is detected that may indicate\nreconnaissance activities.", + "SubSectionObjective": "Ensure that logs and associated alerts are generated when unusual enumeration activity is detected that may indicate reconnaissance activities.", "Applicability": [ "tlp-amber", "tlp-red" ], - "Recommendation": "Implement event publication mechanisms and alerts for patterns\nindicative of enumeration activities, such as repeated access\nattempts, requests, or liveness probes. Configure alerts to notify\nsecurity teams of any activities that merit further investigation.\n", + "Recommendation": "Implement event publication mechanisms and alerts for patterns indicative of enumeration activities, such as repeated access attempts, requests, or liveness probes. Configure alerts to notify security teams of any activities that merit further investigation. ", "SectionThreatMappings": [ { "ReferenceId": "CCC", @@ -8078,21 +6081,21 @@ }, { "Id": "CCC.Core.CN07.AR02", - "Description": "When enumeration activities are detected, the service MUST log the\nclient identity, time, and nature of the activity.", + "Description": "When enumeration activities are detected, the service MUST log the client identity, time, and nature of the activity.", "Attributes": [ { "FamilyName": "Logging & Monitoring", - "FamilyDescription": "The Logging & Monitoring control family ensures that access,\nchanges, and security-relevant events are captured, monitored,\nand alerted on in order to provide visibility, support\nincident response, and meet compliance requirements.\n", + "FamilyDescription": "The Logging & Monitoring control family ensures that access, changes, and security-relevant events are captured, monitored, and alerted on in order to provide visibility, support incident response, and meet compliance requirements. ", "Section": "CCC.Core.CN07 Alert on Unusual Enumeration Activity", "SubSection": "", - "SubSectionObjective": "Ensure that logs and associated alerts are generated when\nunusual enumeration activity is detected that may indicate\nreconnaissance activities.", + "SubSectionObjective": "Ensure that logs and associated alerts are generated when unusual enumeration activity is detected that may indicate reconnaissance activities.", "Applicability": [ "tlp-clear", "tlp-green", "tlp-amber", "tlp-red" ], - "Recommendation": "Implement logging mechanisms to capture details of enumeration\nactivities, including client identity, timestamps, and activity\nnature. Retain logs according to organizational policies, and\noccasionally review them for patterns that may indicate\nreconnaissance activities.\n", + "Recommendation": "Implement logging mechanisms to capture details of enumeration activities, including client identity, timestamps, and activity nature. Retain logs according to organizational policies, and occasionally review them for patterns that may indicate reconnaissance activities. ", "SectionThreatMappings": [ { "ReferenceId": "CCC", diff --git a/prowler/compliance/gcp/ccc_gcp.json b/prowler/compliance/gcp/ccc_gcp.json index 5c780dcbee..e3060646c5 100644 --- a/prowler/compliance/gcp/ccc_gcp.json +++ b/prowler/compliance/gcp/ccc_gcp.json @@ -6,19 +6,19 @@ "Description": "Common Cloud Controls Catalog (CCC) for GCP", "Requirements": [ { - "Id": "CCC.AuditLog.C01.TR01", + "Id": "CCC.AuditLog.CN01.AR01", "Description": "When the signature validation process is performed, then it MUST detect any modification of data.", "Attributes": [ { "FamilyName": "Integrity", "FamilyDescription": "Controls designed to protected the integrity of Audit Log data.", - "Section": "CCC.AuditLog.C01 Implement Digital Signatures With Hash Chaining", + "Section": "CCC.AuditLog.CN01 Implement Digital Signatures With Hash Chaining", "SubSection": "", - "SubSectionObjective": "Digital signatures allows for external verification of log data tampering and\nhash chaining allows for deleted log files to be detected.", + "SubSectionObjective": "Digital signatures allows for external verification of log data tampering and hash chaining allows for deleted log files to be detected.", "Applicability": [ "tlp-red" ], - "Recommendation": "Ensure hash of data is included in digital signature.\n", + "Recommendation": "Ensure hash of data is included in digital signature. ", "SectionThreatMappings": [ { "ReferenceId": "CCC", @@ -52,19 +52,19 @@ ] }, { - "Id": "CCC.AuditLog.C01.TR02", + "Id": "CCC.AuditLog.CN01.AR02", "Description": "When the signature validation process is performed, then it MUST detect any missing (deleted) log file.", "Attributes": [ { "FamilyName": "Integrity", "FamilyDescription": "Controls designed to protected the integrity of Audit Log data.", - "Section": "CCC.AuditLog.C01 Implement Digital Signatures With Hash Chaining", + "Section": "CCC.AuditLog.CN01 Implement Digital Signatures With Hash Chaining", "SubSection": "", - "SubSectionObjective": "Digital signatures allows for external verification of log data tampering and\nhash chaining allows for deleted log files to be detected.", + "SubSectionObjective": "Digital signatures allows for external verification of log data tampering and hash chaining allows for deleted log files to be detected.", "Applicability": [ "tlp-red" ], - "Recommendation": "Ensure verification process includes a chained hash function.\n", + "Recommendation": "Ensure verification process includes a chained hash function. ", "SectionThreatMappings": [ { "ReferenceId": "CCC", @@ -97,15 +97,15 @@ ] }, { - "Id": "CCC.AuditLog.C02.TR01", - "Description": "When a manual action is performed to generate each audit log type,\nthen the corresponding audit log type MUST be generated and recorded.", + "Id": "CCC.AuditLog.CN02.AR01", + "Description": "When a manual action is performed to generate each audit log type, then the corresponding audit log type MUST be generated and recorded.", "Attributes": [ { "FamilyName": "Integrity", "FamilyDescription": "Controls designed to protected the integrity of Audit Log data.", - "Section": "CCC.AuditLog.C02 Enable And Validate All Audit Log Types", + "Section": "CCC.AuditLog.CN02 Enable And Validate All Audit Log Types", "SubSection": "", - "SubSectionObjective": "Review audit log configuration and ensure that all audit log types\nare being generated and replicated to configured sinks", + "SubSectionObjective": "Review audit log configuration and ensure that all audit log types are being generated and replicated to configured sinks", "Applicability": [ "tlp-red", "tlp-amber" @@ -151,20 +151,20 @@ ] }, { - "Id": "CCC.AuditLog.C03.TR01", + "Id": "CCC.AuditLog.CN03.AR01", "Description": "When an attempt is made to disable a log source, then an alert MUST be generated.", "Attributes": [ { "FamilyName": "Integrity", "FamilyDescription": "Controls designed to protected the integrity of Audit Log data.", - "Section": "CCC.AuditLog.C03 Alert On Audit Log Changes And Access", + "Section": "CCC.AuditLog.CN03 Alert On Audit Log Changes And Access", "SubSection": "", - "SubSectionObjective": "Ensure that specific alerts have been configured to detect changes in\naudit log configuration such as disabling exporting of logs.\nAlerts MUST also be created to detect changes in retention/object lock policies\nfor exported data log sources/buckets.", + "SubSectionObjective": "Ensure that specific alerts have been configured to detect changes in audit log configuration such as disabling exporting of logs. Alerts MUST also be created to detect changes in retention/object lock policies for exported data log sources/buckets.", "Applicability": [ "tlp-red", "tlp-amber" ], - "Recommendation": "Ensure alerting is correctly configured\n", + "Recommendation": "Ensure alerting is correctly configured ", "SectionThreatMappings": [ { "ReferenceId": "CCC", @@ -205,20 +205,20 @@ ] }, { - "Id": "CCC.AuditLog.C03.TR02", - "Description": "When an attempt is made to alter the retention or object lock status\nof an external data log source or bucket, then an alert MUST be generated.", + "Id": "CCC.AuditLog.CN03.AR02", + "Description": "When an attempt is made to alter the retention or object lock status of an external data log source or bucket, then an alert MUST be generated.", "Attributes": [ { "FamilyName": "Integrity", "FamilyDescription": "Controls designed to protected the integrity of Audit Log data.", - "Section": "CCC.AuditLog.C03 Alert On Audit Log Changes And Access", + "Section": "CCC.AuditLog.CN03 Alert On Audit Log Changes And Access", "SubSection": "", - "SubSectionObjective": "Ensure that specific alerts have been configured to detect changes in\naudit log configuration such as disabling exporting of logs.\nAlerts MUST also be created to detect changes in retention/object lock policies\nfor exported data log sources/buckets.", + "SubSectionObjective": "Ensure that specific alerts have been configured to detect changes in audit log configuration such as disabling exporting of logs. Alerts MUST also be created to detect changes in retention/object lock policies for exported data log sources/buckets.", "Applicability": [ "tlp-red", "tlp-amber" ], - "Recommendation": "Ensure alerting is correctly configured\n", + "Recommendation": "Ensure alerting is correctly configured ", "SectionThreatMappings": [ { "ReferenceId": "CCC", @@ -251,20 +251,20 @@ ] }, { - "Id": "CCC.AuditLog.C04.TR01", - "Description": "When audit log buckets are created then verify that server access\nlogging MUST be enabled for the audit log bucket,\nwith logs delivered to a separate, secure logging bucket.", + "Id": "CCC.AuditLog.CN04.AR01", + "Description": "When audit log buckets are created then verify that server access logging MUST be enabled for the audit log bucket, with logs delivered to a separate, secure logging bucket.", "Attributes": [ { "FamilyName": "Integrity", "FamilyDescription": "Controls designed to protected the integrity of Audit Log data.", - "Section": "CCC.AuditLog.C04 Ensure Access Logging Is Enabled on the Audit Log Bucket", + "Section": "CCC.AuditLog.CN04 Ensure Access Logging Is Enabled on the Audit Log Bucket", "SubSection": "", - "SubSectionObjective": "Ensure that access logging is enabled for the audit log storage bucket to\ncapture all requests made to the bucket, providing an audit trail of data access.", + "SubSectionObjective": "Ensure that access logging is enabled for the audit log storage bucket to capture all requests made to the bucket, providing an audit trail of data access.", "Applicability": [ "tlp-red", "tlp-amber" ], - "Recommendation": "Configure the audit log bucket to enable server access logging.\nEnsure the target logging bucket is configured for appropriate security,\nincluding restricted access and immutability.\n", + "Recommendation": "Configure the audit log bucket to enable server access logging. Ensure the target logging bucket is configured for appropriate security, including restricted access and immutability. ", "SectionThreatMappings": [ { "ReferenceId": "CCC", @@ -299,20 +299,20 @@ ] }, { - "Id": "CCC.AuditLog.C05.TR01", + "Id": "CCC.AuditLog.CN05.AR01", "Description": "When audit logs are exported, then audit logs MUST be present in the configured data location.", "Attributes": [ { "FamilyName": "Availability", "FamilyDescription": "Controls designed to protected the availability of Audit Log data.", - "Section": "CCC.AuditLog.C05 Export Audit Logs To Bucket", + "Section": "CCC.AuditLog.CN05 Export Audit Logs To Bucket", "SubSection": "", - "SubSectionObjective": "Configure audit logs to be sent to a external bucket where they can be globally replicated\nand can be subject to greater access control and data retention polices.", + "SubSectionObjective": "Configure audit logs to be sent to a external bucket where they can be globally replicated and can be subject to greater access control and data retention polices.", "Applicability": [ "tlp-red", "tlp-amber" ], - "Recommendation": "Configure audit log exporting.\n", + "Recommendation": "Configure audit log exporting. ", "SectionThreatMappings": [ { "ReferenceId": "CCC", @@ -348,21 +348,21 @@ ] }, { - "Id": "CCC.AuditLog.C06.TR01", - "Description": "When the retention policy is applied, then data MUST\nbe automatically deleted after the configured number of days.", + "Id": "CCC.AuditLog.CN06.AR01", + "Description": "When the retention policy is applied, then data MUST be automatically deleted after the configured number of days.", "Attributes": [ { "FamilyName": "Availability", "FamilyDescription": "Controls designed to protected the availability of Audit Log data.", - "Section": "CCC.AuditLog.C06 Enforce Retention Policy on Audit Log Bucket", + "Section": "CCC.AuditLog.CN06 Enforce Retention Policy on Audit Log Bucket", "SubSection": "", - "SubSectionObjective": "Configure a custom retention policy on the designated audit log bucket to ensure that logs are\nretained for the correct number of days as defined by your organization's policy.", + "SubSectionObjective": "Configure a custom retention policy on the designated audit log bucket to ensure that logs are retained for the correct number of days as defined by your organization's policy.", "Applicability": [ "tlp-red", "tlp-amber", "tlp-green" ], - "Recommendation": "Configure the audit log bucket's lifecycle rules or object retention settings to enforce\nthe required data retention period.\n", + "Recommendation": "Configure the audit log bucket's lifecycle rules or object retention settings to enforce the required data retention period. ", "SectionThreatMappings": [ { "ReferenceId": "CCC", @@ -395,21 +395,21 @@ ] }, { - "Id": "CCC.AuditLog.C07.TR01", - "Description": "When a standard file deletion is attempted on an object within\nthe audit log bucket, then it MUST be prevented unless MFA is provided.", + "Id": "CCC.AuditLog.CN07.AR01", + "Description": "When a standard file deletion is attempted on an object within the audit log bucket, then it MUST be prevented unless MFA is provided.", "Attributes": [ { "FamilyName": "Availability", "FamilyDescription": "Controls designed to protected the availability of Audit Log data.", - "Section": "CCC.AuditLog.C07 Enforce MFA Delete on Audit Log Bucket", + "Section": "CCC.AuditLog.CN07 Enforce MFA Delete on Audit Log Bucket", "SubSection": "", - "SubSectionObjective": "Enable Multi-Factor Authentication (MFA) delete on the audit log bucket to\nprovide greater protection against accidental or malicious deletion of audit data.", + "SubSectionObjective": "Enable Multi-Factor Authentication (MFA) delete on the audit log bucket to provide greater protection against accidental or malicious deletion of audit data.", "Applicability": [ "tlp-red", "tlp-amber", "tlp-green" ], - "Recommendation": "Enable MFA Delete (or equivalent multi-factor authentication for delete operations)\non the audit log bucket.\n", + "Recommendation": "Enable MFA Delete (or equivalent multi-factor authentication for delete operations) on the audit log bucket. ", "SectionThreatMappings": [ { "ReferenceId": "CCC", @@ -443,20 +443,20 @@ ] }, { - "Id": "CCC.AuditLog.C08.TR01", - "Description": "When an attempt is made to delete data before the object\nlock period expires, then the deletion MUST be denied.", + "Id": "CCC.AuditLog.CN08.AR01", + "Description": "When an attempt is made to delete data before the object lock period expires, then the deletion MUST be denied.", "Attributes": [ { "FamilyName": "Availability", "FamilyDescription": "Controls designed to protected the availability of Audit Log data.", - "Section": "CCC.AuditLog.C08 Enable Object Lock On Audit Log Bucket", + "Section": "CCC.AuditLog.CN08 Enable Object Lock On Audit Log Bucket", "SubSection": "", - "SubSectionObjective": "Ensure that object log is enabled globally on all objects with the bucket.\nThe lock time MUST be configured to meet your organization, legal and compliance goals.\nDeletion attempts before the lock period MUST be denied.", + "SubSectionObjective": "Ensure that object log is enabled globally on all objects with the bucket. The lock time MUST be configured to meet your organization, legal and compliance goals. Deletion attempts before the lock period MUST be denied.", "Applicability": [ "tlp-red", "tlp-amber" ], - "Recommendation": "Configure object lock policy.\n", + "Recommendation": "Configure object lock policy. ", "SectionThreatMappings": [ { "ReferenceId": "CCC", @@ -487,20 +487,20 @@ ] }, { - "Id": "CCC.AuditLog.C09.TR01", + "Id": "CCC.AuditLog.CN09.AR01", "Description": "When restricted fields are accessed by unauthorized users, then those fields MUST remain masked.", "Attributes": [ { "FamilyName": "Confidentiality", "FamilyDescription": "Controls designed to protected the confidentiality of Audit Log data.", - "Section": "CCC.AuditLog.C09 Restrict Field And Log Type Access", + "Section": "CCC.AuditLog.CN09 Restrict Field And Log Type Access", "SubSection": "", - "SubSectionObjective": "Configure access to audit logs to follow the principle of least privilege in particular where technically\npossible limit the log fields users have access to to prevent accidental exposure to sensitive\ninformation such as PII.", + "SubSectionObjective": "Configure access to audit logs to follow the principle of least privilege in particular where technically possible limit the log fields users have access to to prevent accidental exposure to sensitive information such as PII.", "Applicability": [ "tlp-red", "tlp-amber" ], - "Recommendation": "Review field level access controls on audit data.\n", + "Recommendation": "Review field level access controls on audit data. ", "SectionThreatMappings": [ { "ReferenceId": "CCC", @@ -533,21 +533,21 @@ "Checks": [] }, { - "Id": "CCC.AuditLog.C10.TR01", - "Description": "When audit log storage bucket's are created then, bucket's access control settings MUST explicitly deny\npublic read and write access.", + "Id": "CCC.AuditLog.CN10.AR01", + "Description": "When audit log storage bucket's are created then, bucket's access control settings MUST explicitly deny public read and write access.", "Attributes": [ { "FamilyName": "Confidentiality", "FamilyDescription": "Controls designed to protected the confidentiality of Audit Log data.", - "Section": "CCC.AuditLog.C10 Ensure Audit Bucket is Not Publicly Accessible", + "Section": "CCC.AuditLog.CN10 Ensure Audit Bucket is Not Publicly Accessible", "SubSection": "", - "SubSectionObjective": "Ensure that audit log storage buckets are not publicly accessible to prevent\nunauthorized exposure of sensitive log data.", + "SubSectionObjective": "Ensure that audit log storage buckets are not publicly accessible to prevent unauthorized exposure of sensitive log data.", "Applicability": [ "tlp-red", "tlp-amber", "tlp-green" ], - "Recommendation": "Configure bucket policies and access control lists (ACLs) to restrict public access.\nRegularly review bucket permissions to ensure no public access has been inadvertently granted.\n", + "Recommendation": "Configure bucket policies and access control lists (ACLs) to restrict public access. Regularly review bucket permissions to ensure no public access has been inadvertently granted. ", "SectionThreatMappings": [ { "ReferenceId": "CCC", @@ -580,21 +580,21 @@ ] }, { - "Id": "CCC.AuditLog.C10.TR02", - "Description": "When the URL of a audit log storage bucket's object is accessed publicly then,\nit should be denied by bucket policy.", + "Id": "CCC.AuditLog.CN10.AR02", + "Description": "When the URL of a audit log storage bucket's object is accessed publicly then, it should be denied by bucket policy.", "Attributes": [ { "FamilyName": "Confidentiality", "FamilyDescription": "Controls designed to protected the confidentiality of Audit Log data.", - "Section": "CCC.AuditLog.C10 Ensure Audit Bucket is Not Publicly Accessible", + "Section": "CCC.AuditLog.CN10 Ensure Audit Bucket is Not Publicly Accessible", "SubSection": "", - "SubSectionObjective": "Ensure that audit log storage buckets are not publicly accessible to prevent\nunauthorized exposure of sensitive log data.", + "SubSectionObjective": "Ensure that audit log storage buckets are not publicly accessible to prevent unauthorized exposure of sensitive log data.", "Applicability": [ "tlp-red", "tlp-amber", "tlp-green" ], - "Recommendation": "Configure bucket policies and access control lists (ACLs) to restrict public access.\nRegularly review bucket permissions to ensure no public access has been inadvertently granted.\n", + "Recommendation": "Configure bucket policies and access control lists (ACLs) to restrict public access. Regularly review bucket permissions to ensure no public access has been inadvertently granted. ", "SectionThreatMappings": [ { "ReferenceId": "CCC", @@ -626,7 +626,7 @@ ] }, { - "Id": "CCC.Build.C01.TR01", + "Id": "CCC.Build.CN01.AR01", "Description": "Attempt to initiate a build using an unauthorized build agent and verify that the build is rejected.", "Attributes": [ { @@ -634,7 +634,7 @@ "FamilyDescription": "TODO: Describe this control family", "Section": "", "SubSection": "CCC.Build.C01 Restrict Allowed Build Agents", - "SubSectionObjective": "Ensure that builds are executed only on authorized build agents to maintain\ncontrol over the build environment and prevent unauthorized code execution.", + "SubSectionObjective": "Ensure that builds are executed only on authorized build agents to maintain control over the build environment and prevent unauthorized code execution.", "Applicability": [ "tlp-red", "tlp-amber" @@ -668,15 +668,15 @@ "Checks": [] }, { - "Id": "CCC.Build.C02.TR01", - "Description": "Attempt to trigger a build from an unauthorized external service or\nrepository and verify that the build does not start.", + "Id": "CCC.Build.CN02.AR01", + "Description": "Attempt to trigger a build from an unauthorized external service or repository and verify that the build does not start.", "Attributes": [ { "FamilyName": "Access Control", "FamilyDescription": "TODO: Describe this control family", "Section": "", "SubSection": "CCC.Build.C02 Restrict Allowed External Services for Build Triggers", - "SubSectionObjective": "Ensure that builds can only be triggered by authorized external services or\nrepositories to prevent unauthorized code execution or tampering.", + "SubSectionObjective": "Ensure that builds can only be triggered by authorized external services or repositories to prevent unauthorized code execution or tampering.", "Applicability": [ "tlp-red", "tlp-amber" @@ -710,7 +710,7 @@ "Checks": [] }, { - "Id": "CCC.Build.C03.TR01", + "Id": "CCC.Build.CN03.AR01", "Description": "Attempt to access the build environment from an external network and verify that access is denied.", "Attributes": [ { @@ -718,7 +718,7 @@ "FamilyDescription": "TODO: Describe this control family", "Section": "", "SubSection": "CCC.Build.C03 Deny External Network Access for Build Environments", - "SubSectionObjective": "Ensure that build environments do not have external network access to\nprevent unauthorized external access and data exfiltration.", + "SubSectionObjective": "Ensure that build environments do not have external network access to prevent unauthorized external access and data exfiltration.", "Applicability": [ "tlp-red", "tlp-amber" @@ -760,15 +760,15 @@ ] }, { - "Id": "CCC.CntrReg.C01.TR01", - "Description": "Attempt to push an artifact with known vulnerabilities to the registry\nand observe if it is flagged or rejected by the vulnerability scanning process.", + "Id": "CCC.CntrReg.CN01.AR01", + "Description": "Attempt to push an artifact with known vulnerabilities to the registry and observe if it is flagged or rejected by the vulnerability scanning process.", "Attributes": [ { "FamilyName": "Risk Management", "FamilyDescription": "TODO: Describe this control family", - "Section": "CCC.CntrReg.C01 Implement Vulnerability Scanning for Artifacts", + "Section": "CCC.CntrReg.CN01 Implement Vulnerability Scanning for Artifacts", "SubSection": "", - "SubSectionObjective": "Ensure that container images and artifacts stored in the container registry are scanned for\nvulnerabilities to identify and remediate security issues before deployment.", + "SubSectionObjective": "Ensure that container images and artifacts stored in the container registry are scanned for vulnerabilities to identify and remediate security issues before deployment.", "Applicability": [ "tlp-red", "tlp-amber" @@ -805,56 +805,15 @@ ] }, { - "Id": "CCC.CntrReg.C02.TR01", - "Description": "Confirm that artifacts older than the specified retention period are automatically\ndeleted from the registry.", - "Attributes": [ - { - "FamilyName": "Data Management", - "FamilyDescription": "TODO: Describe this control family", - "Section": "CCC.CntrReg.C02 Implement Cleanup Policies for Artifacts", - "SubSection": "", - "SubSectionObjective": "Ensure that unused or outdated artifacts are cleaned up according to defined policies to\nmanage storage effectively and reduce security risks associated with outdated versions.", - "Applicability": [ - "tlp-red", - "tlp-amber" - ], - "Recommendation": "", - "SectionThreatMappings": [ - { - "ReferenceId": "CCC", - "Identifiers": [ - "CCC.TH14" - ] - } - ], - "SectionGuidelineMappings": [ - { - "ReferenceId": "NIST-CSF", - "Identifiers": [ - "PR.IP-6" - ] - }, - { - "ReferenceId": "NIST_800_53", - "Identifiers": [ - "SI-12" - ] - } - ] - } - ], - "Checks": [] - }, - { - "Id": "CCC.DataWar.C01.TR01", - "Description": "Attempt to access underlying database tables directly without\nusing managed views and verify that access is denied.", + "Id": "CCC.DataWar.CN01.AR01", + "Description": "Attempt to access underlying database tables directly without using managed views and verify that access is denied.", "Attributes": [ { "FamilyName": "Data", "FamilyDescription": "TODO: Describe this control family", - "Section": "CCC.DataWar.C01 Enforce Use of Managed Views for Data Access", + "Section": "CCC.DataWar.CN01 Enforce Use of Managed Views for Data Access", "SubSection": "", - "SubSectionObjective": "Ensure that data access is provided through managed views, restricting users\nfrom accessing underlying tables directly and enforcing consistent security policies.", + "SubSectionObjective": "Ensure that data access is provided through managed views, restricting users from accessing underlying tables directly and enforcing consistent security policies.", "Applicability": [ "tlp-red", "tlp-amber" @@ -888,15 +847,15 @@ "Checks": [] }, { - "Id": "CCC.DataWar.C02.TR01", - "Description": "Attempt to query sensitive columns without the necessary permissions and\nverify that access is denied or data is masked.", + "Id": "CCC.DataWar.CN02.AR01", + "Description": "Attempt to query sensitive columns without the necessary permissions and verify that access is denied or data is masked.", "Attributes": [ { "FamilyName": "Data", "FamilyDescription": "TODO: Describe this control family", - "Section": "CCC.DataWar.C02 Enforce Column-Level Security Policies", + "Section": "CCC.DataWar.CN02 Enforce Column-Level Security Policies", "SubSection": "", - "SubSectionObjective": "Ensure that access to sensitive data columns is restricted based on user roles,\npreventing unauthorized access to sensitive information.", + "SubSectionObjective": "Ensure that access to sensitive data columns is restricted based on user roles, preventing unauthorized access to sensitive information.", "Applicability": [ "tlp-red", "tlp-amber" @@ -930,15 +889,15 @@ "Checks": [] }, { - "Id": "CCC.DataWar.C03.TR01", - "Description": "Attempt to query data rows that the user should not have access to and verify\nthat access is denied or data is not returned.", + "Id": "CCC.DataWar.CN03.AR01", + "Description": "Attempt to query data rows that the user should not have access to and verify that access is denied or data is not returned.", "Attributes": [ { "FamilyName": "Data", "FamilyDescription": "TODO: Describe this control family", - "Section": "CCC.DataWar.C03 Enforce Row-Level Security Policies", + "Section": "CCC.DataWar.CN03 Enforce Row-Level Security Policies", "SubSection": "", - "SubSectionObjective": "Ensure that access to data rows is restricted based on user roles or attributes,\npreventing unauthorized access to specific subsets of data.", + "SubSectionObjective": "Ensure that access to data rows is restricted based on user roles or attributes, preventing unauthorized access to specific subsets of data.", "Applicability": [ "tlp-red", "tlp-amber" @@ -995,730 +954,13 @@ ] }, { - "Id": "CCC.GenAI.C01.TR01", - "Description": "Untrusted input such as user queries, RAG data or tool output\nMUST be validated before it is passed to a GenAI model.", - "Attributes": [ - { - "FamilyName": "Data", - "FamilyDescription": "The Data control family ensures the confidentiality, integrity,\navailability, and sovereignty of data across its lifecycle.\nThese controls govern how data is transmitted, stored,\nreplicated, and protected from unauthorized access, tampering,\nor exposure beyond defined trust perimeters.\n", - "Section": "CCC.GenAI.C01 Model Input Filtering and Sanitisation", - "SubSection": "", - "SubSectionObjective": "Inspect and validate input before it is passed to a GenAI\nmodel in order to filter or sanitise adversarial queries\nand prevent sensitive data leakage.", - "Applicability": [ - "tlp-clear", - "tlp-green", - "tlp-amber", - "tlp-red" - ], - "Recommendation": "", - "SectionThreatMappings": [ - { - "ReferenceId": "CCC", - "Identifiers": [ - "CCC.GenAI.TH01", - "CCC.GenAI.TH03" - ] - } - ], - "SectionGuidelineMappings": [ - { - "ReferenceId": "FINOS-AIGF", - "Identifiers": [ - "AIR-PREV-003", - "AIR-PREV-017", - "AIR-PREV-002", - "AIR-DET-001" - ] - }, - { - "ReferenceId": "SAIF", - "Identifiers": [ - "Input Validation and Sanitization" - ] - }, - { - "ReferenceId": "MITRE-ATLAS", - "Identifiers": [ - "AML.M0020", - "AML.M0021", - "AML.M0015" - ] - } - ] - } - ], - "Checks": [] - }, - { - "Id": "CCC.GenAI.C01.TR02", - "Description": "If malicious patterns such as prompt injection or sensitive\ndata are detected during input validation, the input MUST\nbe blocked or sanitised.", - "Attributes": [ - { - "FamilyName": "Data", - "FamilyDescription": "The Data control family ensures the confidentiality, integrity,\navailability, and sovereignty of data across its lifecycle.\nThese controls govern how data is transmitted, stored,\nreplicated, and protected from unauthorized access, tampering,\nor exposure beyond defined trust perimeters.\n", - "Section": "CCC.GenAI.C01 Model Input Filtering and Sanitisation", - "SubSection": "", - "SubSectionObjective": "Inspect and validate input before it is passed to a GenAI\nmodel in order to filter or sanitise adversarial queries\nand prevent sensitive data leakage.", - "Applicability": [ - "tlp-clear", - "tlp-green", - "tlp-amber", - "tlp-red" - ], - "Recommendation": "", - "SectionThreatMappings": [ - { - "ReferenceId": "CCC", - "Identifiers": [ - "CCC.GenAI.TH01", - "CCC.GenAI.TH03" - ] - } - ], - "SectionGuidelineMappings": [ - { - "ReferenceId": "FINOS-AIGF", - "Identifiers": [ - "AIR-PREV-003", - "AIR-PREV-017", - "AIR-PREV-002", - "AIR-DET-001" - ] - }, - { - "ReferenceId": "SAIF", - "Identifiers": [ - "Input Validation and Sanitization" - ] - }, - { - "ReferenceId": "MITRE-ATLAS", - "Identifiers": [ - "AML.M0020", - "AML.M0021", - "AML.M0015" - ] - } - ] - } - ], - "Checks": [] - }, - { - "Id": "CCC.GenAI.C02.TR01", - "Description": "GenAI model output MUST be validated for format conformance,\nmalicious patterns, sensitive data and inapropriate content\nbefore being passed to users, application or plugins.", - "Attributes": [ - { - "FamilyName": "Data", - "FamilyDescription": "The Data control family ensures the confidentiality, integrity,\navailability, and sovereignty of data across its lifecycle.\nThese controls govern how data is transmitted, stored,\nreplicated, and protected from unauthorized access, tampering,\nor exposure beyond defined trust perimeters.\n", - "Section": "CCC.GenAI.C02 Model Output Filtering and Sanitisation", - "SubSection": "", - "SubSectionObjective": "Inspect and validate GenAI model output before passing it to\nusers, applications or plugins in order to filter or sanitise\ninsecure or unreliable output and prevent sensitive data leakage.", - "Applicability": [ - "tlp-clear", - "tlp-green", - "tlp-amber", - "tlp-red" - ], - "Recommendation": "", - "SectionThreatMappings": [ - { - "ReferenceId": "CCC", - "Identifiers": [ - "CCC.GenAI.TH01", - "CCC.GenAI.TH03", - "CCC.GenAI.TH04", - "CCC.GenAI.TH05", - "CCC.GenAI.TH06" - ] - } - ], - "SectionGuidelineMappings": [ - { - "ReferenceId": "FINOS-AIGF", - "Identifiers": [ - "AIR-PREV-003", - "AIR-PREV-017", - "AIR-PREV-002", - "AIR-DET-001" - ] - }, - { - "ReferenceId": "SAIF", - "Identifiers": [ - "Output Validation and Sanitization" - ] - }, - { - "ReferenceId": "MITRE-ATLAS", - "Identifiers": [ - "AML.M0020", - "AML.M0002" - ] - } - ] - } - ], - "Checks": [] - }, - { - "Id": "CCC.GenAI.C02.TR02", - "Description": "In the event of policy violations, the AI-generated content MUST\nbe redacted, encoded or rejected.", - "Attributes": [ - { - "FamilyName": "Data", - "FamilyDescription": "The Data control family ensures the confidentiality, integrity,\navailability, and sovereignty of data across its lifecycle.\nThese controls govern how data is transmitted, stored,\nreplicated, and protected from unauthorized access, tampering,\nor exposure beyond defined trust perimeters.\n", - "Section": "CCC.GenAI.C02 Model Output Filtering and Sanitisation", - "SubSection": "", - "SubSectionObjective": "Inspect and validate GenAI model output before passing it to\nusers, applications or plugins in order to filter or sanitise\ninsecure or unreliable output and prevent sensitive data leakage.", - "Applicability": [ - "tlp-clear", - "tlp-green", - "tlp-amber", - "tlp-red" - ], - "Recommendation": "", - "SectionThreatMappings": [ - { - "ReferenceId": "CCC", - "Identifiers": [ - "CCC.GenAI.TH01", - "CCC.GenAI.TH03", - "CCC.GenAI.TH04", - "CCC.GenAI.TH05", - "CCC.GenAI.TH06" - ] - } - ], - "SectionGuidelineMappings": [ - { - "ReferenceId": "FINOS-AIGF", - "Identifiers": [ - "AIR-PREV-003", - "AIR-PREV-017", - "AIR-PREV-002", - "AIR-DET-001" - ] - }, - { - "ReferenceId": "SAIF", - "Identifiers": [ - "Output Validation and Sanitization" - ] - }, - { - "ReferenceId": "MITRE-ATLAS", - "Identifiers": [ - "AML.M0020", - "AML.M0002" - ] - } - ] - } - ], - "Checks": [] - }, - { - "Id": "CCC.GenAI.C03.TR01", - "Description": "When data is designated for model training or RAG ingestion, then its\nsource MUST be explicitly approved and its provenance documented.", - "Attributes": [ - { - "FamilyName": "Data", - "FamilyDescription": "The Data control family ensures the confidentiality, integrity,\navailability, and sovereignty of data across its lifecycle.\nThese controls govern how data is transmitted, stored,\nreplicated, and protected from unauthorized access, tampering,\nor exposure beyond defined trust perimeters.\n", - "Section": "CCC.GenAI.C03 Data Provenance and Source Vetting", - "SubSection": "", - "SubSectionObjective": "Ensure that all data for training, fine-tuning or RAG comes\nfrom trusted, approved sources and is authorised for the\nintended purposes in order to prevent the initial introduction\nof malicious content or leaked sensitive data.", - "Applicability": [ - "tlp-clear", - "tlp-green", - "tlp-amber", - "tlp-red" - ], - "Recommendation": "", - "SectionThreatMappings": [ - { - "ReferenceId": "CCC", - "Identifiers": [ - "CCC.GenAI.TH02", - "CCC.GenAI.TH03" - ] - } - ], - "SectionGuidelineMappings": [ - { - "ReferenceId": "FINOS-AIGF", - "Identifiers": [ - "AIR-PREV-006" - ] - }, - { - "ReferenceId": "SAIF", - "Identifiers": [ - "Training Data Management" - ] - }, - { - "ReferenceId": "MITRE-ATLAS", - "Identifiers": [ - "AML.M0025" - ] - } - ] - } - ], - "Checks": [ - "dataproc_encrypted_with_cmks_disabled", - "bigquery_dataset_cmk_encryption", - "bigquery_dataset_public_access", - "bigquery_table_cmk_encryption", - "cloudstorage_bucket_public_access", - "cloudstorage_bucket_uniform_bucket_level_access", - "cloudstorage_bucket_log_retention_policy_lock", - "kms_key_not_publicly_accessible", - "logging_sink_created", - "iam_audit_logs_enabled", - "iam_cloud_asset_inventory_enabled", - "logging_log_metric_filter_and_alert_for_audit_configuration_changes_enabled" - ] - }, - { - "Id": "CCC.GenAI.C03.TR02", - "Description": "Data from unvetted sources MUST NOT be used in production systems.", - "Attributes": [ - { - "FamilyName": "Data", - "FamilyDescription": "The Data control family ensures the confidentiality, integrity,\navailability, and sovereignty of data across its lifecycle.\nThese controls govern how data is transmitted, stored,\nreplicated, and protected from unauthorized access, tampering,\nor exposure beyond defined trust perimeters.\n", - "Section": "CCC.GenAI.C03 Data Provenance and Source Vetting", - "SubSection": "", - "SubSectionObjective": "Ensure that all data for training, fine-tuning or RAG comes\nfrom trusted, approved sources and is authorised for the\nintended purposes in order to prevent the initial introduction\nof malicious content or leaked sensitive data.", - "Applicability": [ - "tlp-clear", - "tlp-green", - "tlp-amber", - "tlp-red" - ], - "Recommendation": "", - "SectionThreatMappings": [ - { - "ReferenceId": "CCC", - "Identifiers": [ - "CCC.GenAI.TH02", - "CCC.GenAI.TH03" - ] - } - ], - "SectionGuidelineMappings": [ - { - "ReferenceId": "FINOS-AIGF", - "Identifiers": [ - "AIR-PREV-006" - ] - }, - { - "ReferenceId": "SAIF", - "Identifiers": [ - "Training Data Management" - ] - }, - { - "ReferenceId": "MITRE-ATLAS", - "Identifiers": [ - "AML.M0025" - ] - } - ] - } - ], - "Checks": [] - }, - { - "Id": "CCC.GenAI.C04.TR01", - "Description": "When data is ingested for training, fine-tuning or conversion\nto vector embeddings, it MUST be validated for sensitive\ninformation or malicious content.", - "Attributes": [ - { - "FamilyName": "Data", - "FamilyDescription": "The Data control family ensures the confidentiality, integrity,\navailability, and sovereignty of data across its lifecycle.\nThese controls govern how data is transmitted, stored,\nreplicated, and protected from unauthorized access, tampering,\nor exposure beyond defined trust perimeters.\n", - "Section": "CCC.GenAI.C04 Sanitisation of Ingested Data", - "SubSection": "", - "SubSectionObjective": "Validate and sanitise all data ingested by GenAI systems\nfrom extenal sources or internal knowledge bases, whether\nfor training, conversion to vector embeddings, or real-time\nretireval, in order to remove or redact poisoned or sensitive\ndata before further processing.", - "Applicability": [ - "tlp-clear", - "tlp-green", - "tlp-amber", - "tlp-red" - ], - "Recommendation": "", - "SectionThreatMappings": [ - { - "ReferenceId": "CCC", - "Identifiers": [ - "CCC.GenAI.TH02", - "CCC.GenAI.TH03" - ] - } - ], - "SectionGuidelineMappings": [ - { - "ReferenceId": "FINOS-AIGF", - "Identifiers": [ - "AIR-PREV-002" - ] - }, - { - "ReferenceId": "SAIF", - "Identifiers": [ - "Training Data Sanitization" - ] - }, - { - "ReferenceId": "MITRE-ATLAS", - "Identifiers": [ - "AML.M0007" - ] - } - ] - } - ], - "Checks": [ - "cloudstorage_bucket_public_access", - "cloudstorage_bucket_uniform_bucket_level_access", - "gcr_container_scanning_enabled", - "compute_instance_public_ip", - "compute_firewall_ssh_access_from_the_internet_allowed", - "compute_firewall_rdp_access_from_the_internet_allowed", - "dataproc_encrypted_with_cmks_disabled", - "bigquery_dataset_public_access", - "bigquery_table_cmk_encryption", - "cloudsql_instance_public_access", - "kms_key_not_publicly_accessible" - ] - }, - { - "Id": "CCC.GenAI.C04.TR02", - "Description": "If sensitive data or malicious content is detected, it must\nbe rejected, redacted or flagged for manual review.", - "Attributes": [ - { - "FamilyName": "Data", - "FamilyDescription": "The Data control family ensures the confidentiality, integrity,\navailability, and sovereignty of data across its lifecycle.\nThese controls govern how data is transmitted, stored,\nreplicated, and protected from unauthorized access, tampering,\nor exposure beyond defined trust perimeters.\n", - "Section": "CCC.GenAI.C04 Sanitisation of Ingested Data", - "SubSection": "", - "SubSectionObjective": "Validate and sanitise all data ingested by GenAI systems\nfrom extenal sources or internal knowledge bases, whether\nfor training, conversion to vector embeddings, or real-time\nretireval, in order to remove or redact poisoned or sensitive\ndata before further processing.", - "Applicability": [ - "tlp-clear", - "tlp-green", - "tlp-amber", - "tlp-red" - ], - "Recommendation": "", - "SectionThreatMappings": [ - { - "ReferenceId": "CCC", - "Identifiers": [ - "CCC.GenAI.TH02", - "CCC.GenAI.TH03" - ] - } - ], - "SectionGuidelineMappings": [ - { - "ReferenceId": "FINOS-AIGF", - "Identifiers": [ - "AIR-PREV-002" - ] - }, - { - "ReferenceId": "SAIF", - "Identifiers": [ - "Training Data Sanitization" - ] - }, - { - "ReferenceId": "MITRE-ATLAS", - "Identifiers": [ - "AML.M0007" - ] - } - ] - } - ], - "Checks": [] - }, - { - "Id": "CCC.GenAI.C05.TR01", - "Description": "When a RAG-enabled system generates a response containing information\nretrieved from its knowledge base, then the response MUST include a\nverifiable citation that links back to the specific source document.", - "Attributes": [ - { - "FamilyName": "Data", - "FamilyDescription": "The Data control family ensures the confidentiality, integrity,\navailability, and sovereignty of data across its lifecycle.\nThese controls govern how data is transmitted, stored,\nreplicated, and protected from unauthorized access, tampering,\nor exposure beyond defined trust perimeters.\n", - "Section": "CCC.GenAI.C05 Citations and Source Traceability", - "SubSection": "", - "SubSectionObjective": "Require the GenAI system to provide citations or direct links\nback to the source documents used to generate a response, in\nto enhance the transparency, trustworthiness, and verifiability\nof AI-generated content.", - "Applicability": [ - "tlp-clear", - "tlp-green", - "tlp-amber", - "tlp-red" - ], - "Recommendation": "", - "SectionThreatMappings": [ - { - "ReferenceId": "CCC", - "Identifiers": [ - "CCC.GenAI.TH09", - "CCC.GenAI.TH04" - ] - } - ], - "SectionGuidelineMappings": [ - { - "ReferenceId": "FINOS-AIGF", - "Identifiers": [ - "AIR-DET-013" - ] - } - ] - } - ], - "Checks": [ - "iam_audit_logs_enabled", - "logging_sink_created", - "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_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", - "iam_cloud_asset_inventory_enabled" - ] - }, - { - "Id": "CCC.GenAI.C06.TR01", - "Description": "When an LLM invokes an external tool (e.g., an API, a plugin),\nthen the tool MUST operate with the least privileges required\nfor performing its intended functionality.", - "Attributes": [ - { - "FamilyName": "Identity and Access Management", - "FamilyDescription": "The Identity and Access Management control family ensures\nthat only trusted and authenticated entities can access\nresources. These controls establish strong authentication,\nenforce multi-factor verification, and restrict access to\napproved sources to prevent unauthorized use or data exfiltration.\n", - "Section": "CCC.GenAI.C06 Least Privilege for Plugins", - "SubSection": "", - "SubSectionObjective": "Restricts the permissions of any external tools the GenAI system\ncan call to limit the potential damage if an agent is coerced\nto perform unintended actions or vulnerabilities in the tools\nare exploited.", - "Applicability": [ - "tlp-clear", - "tlp-green", - "tlp-amber", - "tlp-red" - ], - "Recommendation": "", - "SectionThreatMappings": [ - { - "ReferenceId": "CCC", - "Identifiers": [ - "CCC.GenAI.TH07", - "CCC.GenAI.TH06" - ] - } - ], - "SectionGuidelineMappings": [ - { - "ReferenceId": "SAIF", - "Identifiers": [ - "Agent Permissions" - ] - } - ] - } - ], - "Checks": [ - "apikeys_api_restrictions_configured", - "compute_instance_default_service_account_in_use_with_full_api_access", - "compute_instance_default_service_account_in_use", - "gke_cluster_no_default_service_account", - "iam_no_service_roles_at_project_level", - "iam_sa_no_administrative_privileges", - "iam_sa_no_user_managed_keys", - "iam_sa_user_managed_key_rotate_90_days", - "iam_sa_user_managed_key_unused", - "iam_service_account_unused" - ] - }, - { - "Id": "CCC.GenAI.C07.TR01", - "Description": "When an application makes an API call to a foundational model in a\nproduction environment, then it MUST specify an explicit version\nidentifier.", - "Attributes": [ - { - "FamilyName": "Configuration Management", - "FamilyDescription": "The Configuration Management control family involves establishing,\nmaintaining and monitoring the configuration of the service and\nrelated applications and infrastructure to ensure consistency,\nsecure defaults and compliance.\n", - "Section": "CCC.GenAI.C07 Model Version Pinning", - "SubSection": "", - "SubSectionObjective": "Mandate that applications are locked (\"pinned\") to a specific,\ntested version of a foundational model to prevent unexpected\nbehaviour changes introduced by provider-side updates.", - "Applicability": [ - "tlp-clear", - "tlp-green", - "tlp-amber", - "tlp-red" - ], - "Recommendation": "", - "SectionThreatMappings": [ - { - "ReferenceId": "CCC", - "Identifiers": [ - "CCC.GenAI.TH10" - ] - } - ], - "SectionGuidelineMappings": [ - { - "ReferenceId": "FINOS-AIGF", - "Identifiers": [ - "AIR-PREV-010" - ] - } - ] - } - ], - "Checks": [] - }, - { - "Id": "CCC.GenAI.C08.TR01", - "Description": "When a new AI model is considered for production deployment, it\nMUST undergo a formal red teaming and quality assurance review.", - "Attributes": [ - { - "FamilyName": "Model Assurance and Evaluation", - "FamilyDescription": "The Model Assurance and Evaluation control family encompasses\nthe proactiveand continuous processes of testing and validating\nthe AI model's behavior to ensure it aligns with safety, ethical,\nand quality standards.\n", - "Section": "CCC.GenAI.C08 Quality Control and Red Teaming", - "SubSection": "", - "SubSectionObjective": "Establish a formal program for quality evaluation and adversarial\ntesting (red teaming) to ensure GenAI system meet all business,\nquality, security and compliance requirements before getting deployed\ninto production environments.", - "Applicability": [ - "tlp-clear", - "tlp-green", - "tlp-amber", - "tlp-red" - ], - "Recommendation": "", - "SectionThreatMappings": [ - { - "ReferenceId": "CCC", - "Identifiers": [ - "CCC.GenAI.TH01", - "CCC.GenAI.TH02", - "CCC.GenAI.TH04", - "CCC.GenAI.TH08", - "CCC.GenAI.TH10" - ] - } - ], - "SectionGuidelineMappings": [ - { - "ReferenceId": "FINOS-AIGF", - "Identifiers": [ - "AIR-PREV-005" - ] - }, - { - "ReferenceId": "SAIF", - "Identifiers": [ - "Adversarial Training and Testing", - "Red Teaming", - "Product Governance" - ] - }, - { - "ReferenceId": "MITRE-ATLAS", - "Identifiers": [ - "AML.M0008" - ] - } - ] - } - ], - "Checks": [ - "artifacts_container_analysis_enabled", - "gcr_container_scanning_enabled", - "cloudstorage_bucket_public_access", - "cloudstorage_bucket_log_retention_policy_lock", - "iam_audit_logs_enabled", - "iam_cloud_asset_inventory_enabled", - "logging_sink_created", - "bigquery_dataset_cmk_encryption", - "bigquery_table_cmk_encryption", - "kms_key_not_publicly_accessible", - "kms_key_rotation_enabled", - "dataproc_encrypted_with_cmks_disabled" - ] - }, - { - "Id": "CCC.GenAI.C08.TR02", - "Description": "If model quality review or red teaming identifies an issue that exceeds\nthe organization's risk tolerance, the model MUST NOT be deployed until\nthe issue is remediated.", - "Attributes": [ - { - "FamilyName": "Model Assurance and Evaluation", - "FamilyDescription": "The Model Assurance and Evaluation control family encompasses\nthe proactiveand continuous processes of testing and validating\nthe AI model's behavior to ensure it aligns with safety, ethical,\nand quality standards.\n", - "Section": "CCC.GenAI.C08 Quality Control and Red Teaming", - "SubSection": "", - "SubSectionObjective": "Establish a formal program for quality evaluation and adversarial\ntesting (red teaming) to ensure GenAI system meet all business,\nquality, security and compliance requirements before getting deployed\ninto production environments.", - "Applicability": [ - "tlp-clear", - "tlp-green", - "tlp-amber", - "tlp-red" - ], - "Recommendation": "", - "SectionThreatMappings": [ - { - "ReferenceId": "CCC", - "Identifiers": [ - "CCC.GenAI.TH01", - "CCC.GenAI.TH02", - "CCC.GenAI.TH04", - "CCC.GenAI.TH08", - "CCC.GenAI.TH10" - ] - } - ], - "SectionGuidelineMappings": [ - { - "ReferenceId": "FINOS-AIGF", - "Identifiers": [ - "AIR-PREV-005" - ] - }, - { - "ReferenceId": "SAIF", - "Identifiers": [ - "Adversarial Training and Testing", - "Red Teaming", - "Product Governance" - ] - }, - { - "ReferenceId": "MITRE-ATLAS", - "Identifiers": [ - "AML.M0008" - ] - } - ] - } - ], - "Checks": [ - "dataproc_encrypted_with_cmks_disabled", - "gcr_container_scanning_enabled", - "artifacts_container_analysis_enabled", - "iam_audit_logs_enabled", - "iam_cloud_asset_inventory_enabled", - "logging_sink_created", - "kms_key_not_publicly_accessible", - "bigquery_dataset_cmk_encryption", - "bigquery_dataset_public_access" - ] - }, - { - "Id": "CCC.KeyMgmt.C01.TR01", - "Description": "When a key version is scheduled for deletion or disabled, an\nalert MUST be generated within five minutes.", + "Id": "CCC.KeyMgmt.CN01.AR01", + "Description": "When a key version is scheduled for deletion or disabled, an alert MUST be generated within five minutes.", "Attributes": [ { "FamilyName": "Logging and Metrics Publication", "FamilyDescription": "Controls that collect, alert, and retain key-management events.", - "Section": "CCC.KeyMgmt.C01 Alert on Key-version Changes", + "Section": "CCC.KeyMgmt.CN01 Alert on Key-version Changes", "SubSection": "", "SubSectionObjective": "Generate near-real-time alerts when a KMS key version is disabled or scheduled for deletion, enabling rapid investigation and recovery.", "Applicability": [ @@ -1753,13 +995,13 @@ "Checks": [] }, { - "Id": "CCC.KeyMgmt.C02.TR01", - "Description": "When IAM roles and key policies are reviewed, Decrypt permission\nMUST be granted exclusively to documented authorised principals.", + "Id": "CCC.KeyMgmt.CN02.AR01", + "Description": "When IAM roles and key policies are reviewed, Decrypt permission MUST be granted exclusively to documented authorised principals.", "Attributes": [ { "FamilyName": "Identity and Access Management", "FamilyDescription": "Controls that enforce least-privilege use of KMS operations.", - "Section": "CCC.KeyMgmt.C02 Limit Decrypt Permissions", + "Section": "CCC.KeyMgmt.CN02 Limit Decrypt Permissions", "SubSection": "", "SubSectionObjective": "Restrict the Decrypt operation to authorised principals only, applying the principle of least privilege to protect sensitive data.", "Applicability": [ @@ -1796,13 +1038,13 @@ ] }, { - "Id": "CCC.KeyMgmt.C03.TR01", - "Description": "When rotation settings are examined, rotation MUST be enabled with\nan interval not exceeding 365 days.", + "Id": "CCC.KeyMgmt.CN03.AR01", + "Description": "When rotation settings are examined, rotation MUST be enabled with an interval not exceeding 365 days.", "Attributes": [ { "FamilyName": "Key Lifecycle Management", "FamilyDescription": "Controls that govern creation, rotation, import, and retirement of cryptographic keys.", - "Section": "CCC.KeyMgmt.C03 Enforce Automatic Rotation", + "Section": "CCC.KeyMgmt.CN03 Enforce Automatic Rotation", "SubSection": "", "SubSectionObjective": "Ensure symmetric keys rotate automatically within policy intervals to reduce exposure of key material.", "Applicability": [ @@ -1838,13 +1080,13 @@ ] }, { - "Id": "CCC.KeyMgmt.C04.TR01", - "Description": "When a key import request is processed, the key MUST use an\napproved algorithm (RSA-2048+, EC-P256+) and originate from a\ncertified HSM.", + "Id": "CCC.KeyMgmt.CN04.AR01", + "Description": "When a key import request is processed, the key MUST use an approved algorithm (RSA-2048+, EC-P256+) and originate from a certified HSM.", "Attributes": [ { "FamilyName": "Key Lifecycle Management", "FamilyDescription": "Controls that govern creation, rotation, import, and retirement of cryptographic keys.", - "Section": "CCC.KeyMgmt.C04 Validate Imported Keys", + "Section": "CCC.KeyMgmt.CN04 Validate Imported Keys", "SubSection": "", "SubSectionObjective": "Accept only externally generated keys that meet approved cryptographic strength and provenance requirements.", "Applicability": [ @@ -1881,13 +1123,13 @@ ] }, { - "Id": "CCC.LB.C01.TR01", - "Description": "When a single client sends more than 2000 requests within any\n5-minute sliding window, the load balancer MUST throttle all\nsubsequent requests from that client for at least 60 seconds.", + "Id": "CCC.LB.CN01.AR01", + "Description": "When a single client sends more than 2000 requests within any 5-minute sliding window, the load balancer MUST throttle all subsequent requests from that client for at least 60 seconds.", "Attributes": [ { "FamilyName": "Logging & Monitoring", - "FamilyDescription": "Controls that detect anomalous traffic and record load-balancer activity.\n", - "Section": "CCC.LB.C01 Enforce and Detect Rate Limiting", + "FamilyDescription": "Controls that detect anomalous traffic and record load-balancer activity. ", + "Section": "CCC.LB.CN01 Enforce and Detect Rate Limiting", "SubSection": "", "SubSectionObjective": "Detect and throttle malicious or excessive requests to prevent downstream resource exhaustion and brute-force activity.", "Applicability": [ @@ -1895,7 +1137,7 @@ "tlp-amber", "tlp-red" ], - "Recommendation": "Implement per-IP token-bucket limits with and verify via\nsynthetic traffic tests.\n", + "Recommendation": "Implement per-IP token-bucket limits with and verify via synthetic traffic tests. ", "SectionThreatMappings": [ { "ReferenceId": "LB", @@ -1936,13 +1178,13 @@ ] }, { - "Id": "CCC.LB.C01.TR02", - "Description": "When throttling is invoked, the load balancer MUST\nrecord the event in the access log within 5 minutes\nfor alerting and trend analysis.", + "Id": "CCC.LB.CN01.AR02", + "Description": "When throttling is invoked, the load balancer MUST record the event in the access log within 5 minutes for alerting and trend analysis.", "Attributes": [ { "FamilyName": "Logging & Monitoring", - "FamilyDescription": "Controls that detect anomalous traffic and record load-balancer activity.\n", - "Section": "CCC.LB.C01 Enforce and Detect Rate Limiting", + "FamilyDescription": "Controls that detect anomalous traffic and record load-balancer activity. ", + "Section": "CCC.LB.CN01 Enforce and Detect Rate Limiting", "SubSection": "", "SubSectionObjective": "Detect and throttle malicious or excessive requests to prevent downstream resource exhaustion and brute-force activity.", "Applicability": [ @@ -1950,7 +1192,7 @@ "tlp-amber", "tlp-red" ], - "Recommendation": "Enable access logging and configure metric filters\non HTTP 429 counts to trigger alerts.\n", + "Recommendation": "Enable access logging and configure metric filters on HTTP 429 counts to trigger alerts. ", "SectionThreatMappings": [ { "ReferenceId": "LB", @@ -1986,21 +1228,21 @@ ] }, { - "Id": "CCC.LB.C06.TR01", - "Description": "When more than 10 percent of targets change from healthy to\nunhealthy within five minutes, an alert MUST be issued.", + "Id": "CCC.LB.CN06.AR01", + "Description": "When more than 10 percent of targets change from healthy to unhealthy within five minutes, an alert MUST be issued.", "Attributes": [ { "FamilyName": "Logging & Monitoring", - "FamilyDescription": "Controls that detect anomalous traffic and record load-balancer activity.\n", - "Section": "CCC.LB.C06 Secure Health-Check Telemetry", + "FamilyDescription": "Controls that detect anomalous traffic and record load-balancer activity. ", + "Section": "CCC.LB.CN06 Secure Health-Check Telemetry", "SubSection": "", - "SubSectionObjective": "Monitor health-check endpoints for tampering and alert on\nabnormal status changes.", + "SubSectionObjective": "Monitor health-check endpoints for tampering and alert on abnormal status changes.", "Applicability": [ "tlp-green", "tlp-amber", "tlp-red" ], - "Recommendation": "Instrument metrics for health check results and target\nremoval events. Configure monitoring alarms to alert\non abnormal spikes in unhealthy targets.\n", + "Recommendation": "Instrument metrics for health check results and target removal events. Configure monitoring alarms to alert on abnormal spikes in unhealthy targets. ", "SectionThreatMappings": [ { "ReferenceId": "LB", @@ -2032,21 +1274,21 @@ ] }, { - "Id": "CCC.LB.C04.TR01", - "Description": "When routing weights change, the request MUST originate\nfrom an explicitly defined and trusted identity and MUST\nbe logged.", + "Id": "CCC.LB.CN04.AR01", + "Description": "When routing weights change, the request MUST originate from an explicitly defined and trusted identity and MUST be logged.", "Attributes": [ { "FamilyName": "Identity and Access Management", - "FamilyDescription": "Controls that restrict who can change or query load-balancer resources.\n", - "Section": "CCC.LB.C04 Enforce Distribution Policies", + "FamilyDescription": "Controls that restrict who can change or query load-balancer resources. ", + "Section": "CCC.LB.CN04 Enforce Distribution Policies", "SubSection": "", - "SubSectionObjective": "Ensure traffic-splitting weights and algorithms are modified\nonly by trusted identities.", + "SubSectionObjective": "Ensure traffic-splitting weights and algorithms are modified only by trusted identities.", "Applicability": [ "tlp-green", "tlp-amber", "tlp-red" ], - "Recommendation": "Define a list of trusted principals allowed to modify\nrouting configurations. Enforce via conditional access\npolicies, and log changes using audit logging.\n", + "Recommendation": "Define a list of trusted principals allowed to modify routing configurations. Enforce via conditional access policies, and log changes using audit logging. ", "SectionThreatMappings": [ { "ReferenceId": "LB", @@ -2083,15 +1325,15 @@ ] }, { - "Id": "CCC.LB.C05.TR01", - "Description": "When stickiness is enabled, session cookies MUST expire\nwithin 30 minutes of inactivity.", + "Id": "CCC.LB.CN05.AR01", + "Description": "When stickiness is enabled, session cookies MUST expire within 30 minutes of inactivity.", "Attributes": [ { "FamilyName": "Identity and Access Management", - "FamilyDescription": "Controls that restrict who can change or query load-balancer resources.\n", - "Section": "CCC.LB.C05 Validate Session Affinity", + "FamilyDescription": "Controls that restrict who can change or query load-balancer resources. ", + "Section": "CCC.LB.CN05 Validate Session Affinity", "SubSection": "", - "SubSectionObjective": "Configure session persistence to minimise fixation and hijacking\nrisks.", + "SubSectionObjective": "Configure session persistence to minimise fixation and hijacking risks.", "Applicability": [ "tlp-green", "tlp-amber", @@ -2139,15 +1381,15 @@ ] }, { - "Id": "CCC.LB.C09.TR01", - "Description": "When an API call originates outside the approved CIDR\nset, the request MUST be denied.", + "Id": "CCC.LB.CN09.AR01", + "Description": "When an API call originates outside the approved CIDR set, the request MUST be denied.", "Attributes": [ { "FamilyName": "Identity and Access Management", - "FamilyDescription": "Controls that restrict who can change or query load-balancer resources.\n", - "Section": "CCC.LB.C09 Restrict Management API Access", + "FamilyDescription": "Controls that restrict who can change or query load-balancer resources. ", + "Section": "CCC.LB.CN09 Restrict Management API Access", "SubSection": "", - "SubSectionObjective": "Limit load-balancer API calls to authorised identities and\ntrusted networks.", + "SubSectionObjective": "Limit load-balancer API calls to authorised identities and trusted networks.", "Applicability": [ "tlp-green", "tlp-amber", @@ -2194,15 +1436,15 @@ ] }, { - "Id": "CCC.LB.C02.TR01", - "Description": "When concurrent connections reach 80 percent of capacity, the\nautoscaling group MUST add at least one instance within five\nminutes.", + "Id": "CCC.LB.CN02.AR01", + "Description": "When concurrent connections reach 80 percent of capacity, the autoscaling group MUST add at least one instance within five minutes.", "Attributes": [ { "FamilyName": "Data", - "FamilyDescription": "Controls that preserve availability and confidentiality of\ntraffic processed by the load balancer.\n", - "Section": "CCC.LB.C02 Auto-Scale Load Balancer Capacity", + "FamilyDescription": "Controls that preserve availability and confidentiality of traffic processed by the load balancer. ", + "Section": "CCC.LB.CN02 Auto-Scale Load Balancer Capacity", "SubSection": "", - "SubSectionObjective": "Expand load-balancer capacity to maintain availability during traffic\nspikes.", + "SubSectionObjective": "Expand load-balancer capacity to maintain availability during traffic spikes.", "Applicability": [ "tlp-green", "tlp-amber", @@ -2236,15 +1478,15 @@ "Checks": [] }, { - "Id": "CCC.LB.C07.TR01", - "Description": "When responses pass through the load balancer, the\n\"Server\" header MUST be replaced with \"lb\".", + "Id": "CCC.LB.CN07.AR01", + "Description": "When responses pass through the load balancer, the \"Server\" header MUST be replaced with \"lb\".", "Attributes": [ { "FamilyName": "Data", - "FamilyDescription": "Controls that preserve availability and confidentiality of\ntraffic processed by the load balancer.\n", - "Section": "CCC.LB.C07 Scrub Sensitive Headers", + "FamilyDescription": "Controls that preserve availability and confidentiality of traffic processed by the load balancer. ", + "Section": "CCC.LB.CN07 Scrub Sensitive Headers", "SubSection": "", - "SubSectionObjective": "Remove headers that disclose internal details or software\nversions from HTTP responses.", + "SubSectionObjective": "Remove headers that disclose internal details or software versions from HTTP responses.", "Applicability": [ "tlp-green", "tlp-amber", @@ -2278,15 +1520,15 @@ "Checks": [] }, { - "Id": "CCC.LB.C08.TR01", - "Description": "When a certificate is within 30 days of expiry, automated renewal\nMUST complete and deploy a new certificate within 24 hours.", + "Id": "CCC.LB.CN08.AR01", + "Description": "When a certificate is within 30 days of expiry, automated renewal MUST complete and deploy a new certificate within 24 hours.", "Attributes": [ { "FamilyName": "Encryption", "FamilyDescription": "Controls that ensure trustworthy TLS certificates and ciphers.", - "Section": "CCC.LB.C08 Automate Certificate Renewal", + "Section": "CCC.LB.CN08 Automate Certificate Renewal", "SubSection": "", - "SubSectionObjective": "Maintain valid TLS certificates by automating renewal and\ndeployment before expiry.", + "SubSectionObjective": "Maintain valid TLS certificates by automating renewal and deployment before expiry.", "Applicability": [ "tlp-green", "tlp-amber", @@ -2320,15 +1562,15 @@ "Checks": [] }, { - "Id": "CCC.Logging.C01.TR01", - "Description": "When a new cloud account is created, provider-level audit and network flow logging MUST be\nenabled by default and directed to the central sink.", + "Id": "CCC.Logging.CN01.AR01", + "Description": "When a new cloud account is created, provider-level audit and network flow logging MUST be enabled by default and directed to the central sink.", "Attributes": [ { "FamilyName": "Data", - "FamilyDescription": "Controls related to the confidentiality, integrity and availability of log data.\n", - "Section": "CCC.Logging.C01 Centralized and Comprehensive Log Aggregation", + "FamilyDescription": "Controls related to the confidentiality, integrity and availability of log data. ", + "Section": "CCC.Logging.CN01 Centralized and Comprehensive Log Aggregation", "SubSection": "", - "SubSectionObjective": "Ensure all operational and security logs from across the cloud environment, including\napplications, operating systems, network traffic, and cloud service activity, are captured\nautomatically and streamed to a central, secure log management service.", + "SubSectionObjective": "Ensure all operational and security logs from across the cloud environment, including applications, operating systems, network traffic, and cloud service activity, are captured automatically and streamed to a central, secure log management service.", "Applicability": [ "tlp-clear", "tlp-green", @@ -2368,15 +1610,15 @@ ] }, { - "Id": "CCC.Logging.C01.TR02", - "Description": "When a new cloud compute resource is deployed, it MUST be configured to forward all relevant\nlogs (e.g., OS, application, service logs) to the central log sink.", + "Id": "CCC.Logging.CN01.AR02", + "Description": "When a new cloud compute resource is deployed, it MUST be configured to forward all relevant logs (e.g., OS, application, service logs) to the central log sink.", "Attributes": [ { "FamilyName": "Data", - "FamilyDescription": "Controls related to the confidentiality, integrity and availability of log data.\n", - "Section": "CCC.Logging.C01 Centralized and Comprehensive Log Aggregation", + "FamilyDescription": "Controls related to the confidentiality, integrity and availability of log data. ", + "Section": "CCC.Logging.CN01 Centralized and Comprehensive Log Aggregation", "SubSection": "", - "SubSectionObjective": "Ensure all operational and security logs from across the cloud environment, including\napplications, operating systems, network traffic, and cloud service activity, are captured\nautomatically and streamed to a central, secure log management service.", + "SubSectionObjective": "Ensure all operational and security logs from across the cloud environment, including applications, operating systems, network traffic, and cloud service activity, are captured automatically and streamed to a central, secure log management service.", "Applicability": [ "tlp-clear", "tlp-green", @@ -2419,15 +1661,15 @@ ] }, { - "Id": "CCC.Logging.C02.TR01", - "Description": "When a new log bucket or stream is created, its retention policy MUST be configured\nin accordance with organisation's data retention policy.", + "Id": "CCC.Logging.CN02.AR01", + "Description": "When a new log bucket or stream is created, its retention policy MUST be configured in accordance with organisation's data retention policy.", "Attributes": [ { "FamilyName": "Data", - "FamilyDescription": "Controls related to the confidentiality, integrity and availability of log data.\n", - "Section": "CCC.Logging.C02 Enforce Data Retention Policy for Logs", + "FamilyDescription": "Controls related to the confidentiality, integrity and availability of log data. ", + "Section": "CCC.Logging.CN02 Enforce Data Retention Policy for Logs", "SubSection": "", - "SubSectionObjective": "Ensure that the retention period configured for logs aligns with the organization's\ndata retention policy.", + "SubSectionObjective": "Ensure that the retention period configured for logs aligns with the organization's data retention policy.", "Applicability": [ "tlp-clear", "tlp-green", @@ -2464,15 +1706,15 @@ ] }, { - "Id": "CCC.Logging.C02.TR02", - "Description": "When a query is performed to retrieve log events older than the number of days defined\nin the organisation's data retention policy, it MUST return an empty result.", + "Id": "CCC.Logging.CN02.AR02", + "Description": "When a query is performed to retrieve log events older than the number of days defined in the organisation's data retention policy, it MUST return an empty result.", "Attributes": [ { "FamilyName": "Data", - "FamilyDescription": "Controls related to the confidentiality, integrity and availability of log data.\n", - "Section": "CCC.Logging.C02 Enforce Data Retention Policy for Logs", + "FamilyDescription": "Controls related to the confidentiality, integrity and availability of log data. ", + "Section": "CCC.Logging.CN02 Enforce Data Retention Policy for Logs", "SubSection": "", - "SubSectionObjective": "Ensure that the retention period configured for logs aligns with the organization's\ndata retention policy.", + "SubSectionObjective": "Ensure that the retention period configured for logs aligns with the organization's data retention policy.", "Applicability": [ "tlp-clear", "tlp-green", @@ -2509,20 +1751,20 @@ ] }, { - "Id": "CCC.AuditLog.C08.TR01", - "Description": "When an attempt is made to modify or delete data before the object\nlock period expires, then the action MUST be denied.", + "Id": "CCC.AuditLog.CN08.AR01", + "Description": "When an attempt is made to modify or delete data before the object lock period expires, then the action MUST be denied.", "Attributes": [ { "FamilyName": "Data", - "FamilyDescription": "Controls related to the confidentiality, integrity and availability of log data.\n", - "Section": "CCC.Logging.C03 Enable Object Lock On Log Bucket", + "FamilyDescription": "Controls related to the confidentiality, integrity and availability of log data. ", + "Section": "CCC.Logging.CN03 Enable Object Lock On Log Bucket", "SubSection": "", - "SubSectionObjective": "Ensure log immutability by enabling Write Once, Read Many (WORM) protection\nusing object lock on log storage buckets. This prevents logs from being modified\nor deleted during the defined retention period, supporting compliance and forensic\nintegrity.", + "SubSectionObjective": "Ensure log immutability by enabling Write Once, Read Many (WORM) protection using object lock on log storage buckets. This prevents logs from being modified or deleted during the defined retention period, supporting compliance and forensic integrity.", "Applicability": [ "tlp-red", "tlp-amber" ], - "Recommendation": "Configure object lock policy.\n", + "Recommendation": "Configure object lock policy. ", "SectionThreatMappings": [ { "ReferenceId": "CCC", @@ -2553,20 +1795,20 @@ ] }, { - "Id": "CCC.AuditLog.C04.TR01", + "Id": "CCC.AuditLog.CN04.AR01", "Description": "When restricted fields are accessed by unauthorized users, then those fields MUST remain masked.", "Attributes": [ { "FamilyName": "Identity and Access Management", - "FamilyDescription": "Controls that restrict who can access and modify logs.\n", - "Section": "CCC.Logging.C04 Restrict Field And Log Type Access", + "FamilyDescription": "Controls that restrict who can access and modify logs. ", + "Section": "CCC.Logging.CN04 Restrict Field And Log Type Access", "SubSection": "", - "SubSectionObjective": "Configure access to logs to follow the principle of least privilege in particular where technically\npossible limit the log fields users have access to to prevent accidental exposure to sensitive\ninformation such as PII.", + "SubSectionObjective": "Configure access to logs to follow the principle of least privilege in particular where technically possible limit the log fields users have access to to prevent accidental exposure to sensitive information such as PII.", "Applicability": [ "tlp-red", "tlp-amber" ], - "Recommendation": "Review field level access controls on log data.\n", + "Recommendation": "Review field level access controls on log data. ", "SectionThreatMappings": [ { "ReferenceId": "CCC", @@ -2599,21 +1841,21 @@ "Checks": [] }, { - "Id": "CCC.Logging.C05.TR01", - "Description": "When a log storage bucket is created, the bucket's access control settings MUST\nexplicitly deny public read and write access.", + "Id": "CCC.Logging.CN05.AR01", + "Description": "When a log storage bucket is created, the bucket's access control settings MUST explicitly deny public read and write access.", "Attributes": [ { "FamilyName": "Identity and Access Management", - "FamilyDescription": "Controls that restrict who can access and modify logs.\n", - "Section": "CCC.Logging.C05 Ensure Log Bucket is Not Publicly Accessible", + "FamilyDescription": "Controls that restrict who can access and modify logs. ", + "Section": "CCC.Logging.CN05 Ensure Log Bucket is Not Publicly Accessible", "SubSection": "", - "SubSectionObjective": "Ensure that log storage buckets are not publicly accessible to prevent unauthorized\naccess to sensitive log data. In addition, logs should be replicated to another cloud\nregion to enhance availability, durability, and support disaster recovery requirements.", + "SubSectionObjective": "Ensure that log storage buckets are not publicly accessible to prevent unauthorized access to sensitive log data. In addition, logs should be replicated to another cloud region to enhance availability, durability, and support disaster recovery requirements.", "Applicability": [ "tlp-red", "tlp-amber", "tlp-green" ], - "Recommendation": "Configure bucket policies and access control lists (ACLs) to restrict public access.\nRegularly review bucket permissions to ensure no public access has been inadvertently granted.\n", + "Recommendation": "Configure bucket policies and access control lists (ACLs) to restrict public access. Regularly review bucket permissions to ensure no public access has been inadvertently granted. ", "SectionThreatMappings": [ { "ReferenceId": "CCC", @@ -2647,21 +1889,21 @@ ] }, { - "Id": "CCC.Logging.C05.TR02", - "Description": "When the URL of a log storage bucket's object is accessed publicly, the action MUST be denied\nby bucket policy.", + "Id": "CCC.Logging.CN05.AR02", + "Description": "When the URL of a log storage bucket's object is accessed publicly, the action MUST be denied by bucket policy.", "Attributes": [ { "FamilyName": "Identity and Access Management", - "FamilyDescription": "Controls that restrict who can access and modify logs.\n", - "Section": "CCC.Logging.C05 Ensure Log Bucket is Not Publicly Accessible", + "FamilyDescription": "Controls that restrict who can access and modify logs. ", + "Section": "CCC.Logging.CN05 Ensure Log Bucket is Not Publicly Accessible", "SubSection": "", - "SubSectionObjective": "Ensure that log storage buckets are not publicly accessible to prevent unauthorized\naccess to sensitive log data. In addition, logs should be replicated to another cloud\nregion to enhance availability, durability, and support disaster recovery requirements.", + "SubSectionObjective": "Ensure that log storage buckets are not publicly accessible to prevent unauthorized access to sensitive log data. In addition, logs should be replicated to another cloud region to enhance availability, durability, and support disaster recovery requirements.", "Applicability": [ "tlp-red", "tlp-amber", "tlp-green" ], - "Recommendation": "Configure bucket policies and access control lists (ACLs) to restrict public access.\nRegularly review bucket permissions to ensure no public access has been inadvertently granted.\n", + "Recommendation": "Configure bucket policies and access control lists (ACLs) to restrict public access. Regularly review bucket permissions to ensure no public access has been inadvertently granted. ", "SectionThreatMappings": [ { "ReferenceId": "CCC", @@ -2693,15 +1935,15 @@ ] }, { - "Id": "CCC.Logging.C06.TR01", - "Description": "When a single principal executes an anomalously high number of log queries,\nan alert MUST be generated.", + "Id": "CCC.Logging.CN06.AR01", + "Description": "When a single principal executes an anomalously high number of log queries, an alert MUST be generated.", "Attributes": [ { "FamilyName": "Logging and Monitoring", - "FamilyDescription": "Controls that collect, alert, and retain logging-related events.\n", - "Section": "CCC.Logging.C06 Detect and Alert on Potential Log Exfiltration", + "FamilyDescription": "Controls that collect, alert, and retain logging-related events. ", + "Section": "CCC.Logging.CN06 Detect and Alert on Potential Log Exfiltration", "SubSection": "", - "SubSectionObjective": "Identify and alert on anomalous data access patterns that may indicate an attempt\nto exfiltrate log data.", + "SubSectionObjective": "Identify and alert on anomalous data access patterns that may indicate an attempt to exfiltrate log data.", "Applicability": [ "tlp-green", "tlp-amber", @@ -2748,15 +1990,15 @@ ] }, { - "Id": "CCC.Logging.C07.TR01", - "Description": "When an audit log event is recorded that corresponds to a modification of the logging service\nconfiguration such as disabling a log trail, deleting a log sink, or altering a log forwarding rule,\nan alert MUST be generated.", + "Id": "CCC.Logging.CN07.AR01", + "Description": "When an audit log event is recorded that corresponds to a modification of the logging service configuration such as disabling a log trail, deleting a log sink, or altering a log forwarding rule, an alert MUST be generated.", "Attributes": [ { "FamilyName": "Logging and Monitoring", - "FamilyDescription": "Controls that collect, alert, and retain logging-related events.\n", - "Section": "CCC.Logging.C07 Detect and Alert on Log Service Tampering", + "FamilyDescription": "Controls that collect, alert, and retain logging-related events. ", + "Section": "CCC.Logging.CN07 Detect and Alert on Log Service Tampering", "SubSection": "", - "SubSectionObjective": "Alert when any component of the critical logging infrastructure is disabled, modified,\nor deleted, indicating a defense evasion attempt.", + "SubSectionObjective": "Alert when any component of the critical logging infrastructure is disabled, modified, or deleted, indicating a defense evasion attempt.", "Applicability": [ "tlp-clear", "tlp-green", @@ -2803,13 +2045,13 @@ ] }, { - "Id": "CCC.ObjStor.C01.TR01", + "Id": "CCC.ObjStor.CN01.AR01", "Description": "When a request is made to read a protected bucket, the service MUST prevent any request using KMS keys not listed as trusted by the organization.", "Attributes": [ { "FamilyName": "Data", "FamilyDescription": "TODO: Describe this control family", - "Section": "CCC.C01 Prevent Unencrypted Requests", + "Section": "CCC.CN01 Prevent Unencrypted Requests", "SubSection": "CCC.ObjStor.C01 Prevent Requests to Buckets or Objects with Untrusted KMS Keys", "SubSectionObjective": "Prevent any requests to object storage buckets or objects using untrusted KMS keys to protect against unauthorized data encryption that can impact data availability and integrity.", "Applicability": [ @@ -2861,13 +2103,13 @@ ] }, { - "Id": "CCC.ObjStor.C01.TR02", + "Id": "CCC.ObjStor.CN01.AR02", "Description": "When a request is made to read a protected object, the service MUST prevent any request using KMS keys not listed as trusted by the organization.", "Attributes": [ { "FamilyName": "Data", "FamilyDescription": "TODO: Describe this control family", - "Section": "CCC.C01 Prevent Unencrypted Requests", + "Section": "CCC.CN01 Prevent Unencrypted Requests", "SubSection": "CCC.ObjStor.C01 Prevent Requests to Buckets or Objects with Untrusted KMS Keys", "SubSectionObjective": "Prevent any requests to object storage buckets or objects using untrusted KMS keys to protect against unauthorized data encryption that can impact data availability and integrity.", "Applicability": [ @@ -2916,13 +2158,13 @@ "Checks": [] }, { - "Id": "CCC.ObjStor.C01.TR03", + "Id": "CCC.ObjStor.CN01.AR03", "Description": "When a request is made to write to a bucket, the service MUST prevent any request using KMS keys not listed as trusted by the organization.", "Attributes": [ { "FamilyName": "Data", "FamilyDescription": "TODO: Describe this control family", - "Section": "CCC.C01 Prevent Unencrypted Requests", + "Section": "CCC.CN01 Prevent Unencrypted Requests", "SubSection": "CCC.ObjStor.C01 Prevent Requests to Buckets or Objects with Untrusted KMS Keys", "SubSectionObjective": "Prevent any requests to object storage buckets or objects using untrusted KMS keys to protect against unauthorized data encryption that can impact data availability and integrity.", "Applicability": [ @@ -2979,13 +2221,13 @@ ] }, { - "Id": "CCC.ObjStor.C01.TR04", + "Id": "CCC.ObjStor.CN01.AR04", "Description": "When a request is made to write to an object, the service MUST prevent any request using KMS keys not listed as trusted by the organization.", "Attributes": [ { "FamilyName": "Data", "FamilyDescription": "TODO: Describe this control family", - "Section": "CCC.C01 Prevent Unencrypted Requests", + "Section": "CCC.CN01 Prevent Unencrypted Requests", "SubSection": "CCC.ObjStor.C01 Prevent Requests to Buckets or Objects with Untrusted KMS Keys", "SubSectionObjective": "Prevent any requests to object storage buckets or objects using untrusted KMS keys to protect against unauthorized data encryption that can impact data availability and integrity.", "Applicability": [ @@ -3043,13 +2285,13 @@ ] }, { - "Id": "CCC.ObjStor.C03.TR01", + "Id": "CCC.ObjStor.CN03.AR01", "Description": "When an object storage bucket deletion is attempted, the bucket MUST be fully recoverable for a set time-frame after deletion is requested.", "Attributes": [ { "FamilyName": "Data", "FamilyDescription": "TODO: Describe this control family", - "Section": "CCC.C03 Implement Multi-factor Authentication (MFA) for Access", + "Section": "CCC.CN03 Implement Multi-factor Authentication (MFA) for Access", "SubSection": "CCC.ObjStor.C03 Prevent Bucket Deletion Through Irrevocable Bucket Retention Policy", "SubSectionObjective": "Ensure that object storage bucket is not deleted after creation, and that the preventative measure cannot be unset.", "Applicability": [ @@ -3101,13 +2343,13 @@ ] }, { - "Id": "CCC.ObjStor.C03.TR02", + "Id": "CCC.ObjStor.CN03.AR02", "Description": "When an attempt is made to modify the retention policy for an object storage bucket, the service MUST prevent the policy from being modified.", "Attributes": [ { "FamilyName": "Data", "FamilyDescription": "TODO: Describe this control family", - "Section": "CCC.C03 Implement Multi-factor Authentication (MFA) for Access", + "Section": "CCC.CN03 Implement Multi-factor Authentication (MFA) for Access", "SubSection": "CCC.ObjStor.C03 Prevent Bucket Deletion Through Irrevocable Bucket Retention Policy", "SubSectionObjective": "Ensure that object storage bucket is not deleted after creation, and that the preventative measure cannot be unset.", "Applicability": [ @@ -3159,13 +2401,13 @@ ] }, { - "Id": "CCC.ObjStor.C04.TR01", + "Id": "CCC.ObjStor.CN04.AR01", "Description": "When an object is uploaded to the object storage system, the object MUST automatically receive a default retention policy that prevents premature deletion or modification.", "Attributes": [ { "FamilyName": "Data", "FamilyDescription": "TODO: Describe this control family", - "Section": "CCC.C04 Log All Access and Changes", + "Section": "CCC.CN04 Log All Access and Changes", "SubSection": "CCC.ObjStor.C04 Objects have an Effective Retention Policy by Default", "SubSectionObjective": "Ensure that all objects stored in the object storage system have a retention policy applied by default, preventing premature deletion or modification of objects and ensuring compliance with data retention regulations.", "Applicability": [ @@ -3217,13 +2459,13 @@ ] }, { - "Id": "CCC.ObjStor.C04.TR02", + "Id": "CCC.ObjStor.CN04.AR02", "Description": "When an attempt is made to delete or modify an object that is subject to an active retention policy, the service MUST prevent the action from being completed.", "Attributes": [ { "FamilyName": "Data", "FamilyDescription": "TODO: Describe this control family", - "Section": "CCC.C04 Log All Access and Changes", + "Section": "CCC.CN04 Log All Access and Changes", "SubSection": "CCC.ObjStor.C04 Objects have an Effective Retention Policy by Default", "SubSectionObjective": "Ensure that all objects stored in the object storage system have a retention policy applied by default, preventing premature deletion or modification of objects and ensuring compliance with data retention regulations.", "Applicability": [ @@ -3275,13 +2517,13 @@ ] }, { - "Id": "CCC.ObjStor.C05.TR01", + "Id": "CCC.ObjStor.CN05.AR01", "Description": "When an object is uploaded to the object storage bucket, the object MUST be stored with a unique identifier.", "Attributes": [ { "FamilyName": "Data", "FamilyDescription": "TODO: Describe this control family", - "Section": "CCC.C05 Prevent Access from Untrusted Entities", + "Section": "CCC.CN05 Prevent Access from Untrusted Entities", "SubSection": "CCC.ObjStor.C05 Versioning is Enabled for All Objects in the Bucket", "SubSectionObjective": "Ensure that versioning is enabled for all objects stored in the object storage bucket to enable recovery of previous versions of objects in case of loss or corruption.", "Applicability": [ @@ -3331,13 +2573,13 @@ "Checks": [] }, { - "Id": "CCC.ObjStor.C05.TR02", + "Id": "CCC.ObjStor.CN05.AR02", "Description": "When an object is modified, the service MUST assign a new unique identifier to the modified object to differentiate it from the previous version.", "Attributes": [ { "FamilyName": "Data", "FamilyDescription": "TODO: Describe this control family", - "Section": "CCC.C05 Prevent Access from Untrusted Entities", + "Section": "CCC.CN05 Prevent Access from Untrusted Entities", "SubSection": "CCC.ObjStor.C05 Versioning is Enabled for All Objects in the Bucket", "SubSectionObjective": "Ensure that versioning is enabled for all objects stored in the object storage bucket to enable recovery of previous versions of objects in case of loss or corruption.", "Applicability": [ @@ -3387,13 +2629,13 @@ "Checks": [] }, { - "Id": "CCC.ObjStor.C05.TR03", + "Id": "CCC.ObjStor.CN05.AR03", "Description": "When an object is modified, the service MUST allow for recovery of previous versions of the object.", "Attributes": [ { "FamilyName": "Data", "FamilyDescription": "TODO: Describe this control family", - "Section": "CCC.C05 Prevent Access from Untrusted Entities", + "Section": "CCC.CN05 Prevent Access from Untrusted Entities", "SubSection": "CCC.ObjStor.C05 Versioning is Enabled for All Objects in the Bucket", "SubSectionObjective": "Ensure that versioning is enabled for all objects stored in the object storage bucket to enable recovery of previous versions of objects in case of loss or corruption.", "Applicability": [ @@ -3443,13 +2685,13 @@ "Checks": [] }, { - "Id": "CCC.ObjStor.C05.TR04", + "Id": "CCC.ObjStor.CN05.AR04", "Description": "When an object is deleted, the service MUST retain other versions of the object to allow for recovery of previous versions.", "Attributes": [ { "FamilyName": "Data", "FamilyDescription": "TODO: Describe this control family", - "Section": "CCC.C05 Prevent Access from Untrusted Entities", + "Section": "CCC.CN05 Prevent Access from Untrusted Entities", "SubSection": "CCC.ObjStor.C05 Versioning is Enabled for All Objects in the Bucket", "SubSectionObjective": "Ensure that versioning is enabled for all objects stored in the object storage bucket to enable recovery of previous versions of objects in case of loss or corruption.", "Applicability": [ @@ -3499,13 +2741,13 @@ "Checks": [] }, { - "Id": "CCC.ObjStor.C06.TR01", + "Id": "CCC.ObjStor.CN06.AR01", "Description": "When an object storage bucket is accessed, the service MUST store access logs in a separate data store.", "Attributes": [ { "FamilyName": "Data", "FamilyDescription": "TODO: Describe this control family", - "Section": "CCC.C06 Prevent Deployment in Restricted Regions", + "Section": "CCC.CN06 Prevent Deployment in Restricted Regions", "SubSection": "CCC.ObjStor.C06 Access Logs are Stored in a Separate Data Store", "SubSectionObjective": "Ensure that access logs for object storage buckets are stored in a separate data store to protect against unauthorized access, tampering, or deletion of logs (Logbuckets are exempt from this requirement, but must be tlp-red).", "Applicability": [ @@ -3558,13 +2800,13 @@ ] }, { - "Id": "CCC.ObjStor.C02.TR01", + "Id": "CCC.ObjStor.CN02.AR01", "Description": "When a permission set is allowed for an object in a bucket, the service MUST allow the same permission set to access all objects in the same bucket.", "Attributes": [ { "FamilyName": "Identity and Access Management", "FamilyDescription": "TODO: Describe this control family", - "Section": "CCC.C02 Ensure Data Encryption at Rest for All Stored Data", + "Section": "CCC.CN02 Ensure Data Encryption at Rest for All Stored Data", "SubSection": "CCC.ObjStor.C02 Enforce Uniform Bucket-level Access to Prevent Inconsistent Permissions", "SubSectionObjective": "Ensure that uniform bucket-level access is enforced across all object storage buckets. This prevents the use of ad-hoc or inconsistent object-level permissions, ensuring centralized, consistent, and secure access management in accordance with the principle of least privilege.", "Applicability": [ @@ -3616,13 +2858,13 @@ ] }, { - "Id": "CCC.ObjStor.C02.TR02", + "Id": "CCC.ObjStor.CN02.AR02", "Description": "When a permission set is denied for an object in a bucket, the service MUST deny the same permission set to access all objects in the same bucket.", "Attributes": [ { "FamilyName": "Identity and Access Management", "FamilyDescription": "TODO: Describe this control family", - "Section": "CCC.C02 Ensure Data Encryption at Rest for All Stored Data", + "Section": "CCC.CN02 Ensure Data Encryption at Rest for All Stored Data", "SubSection": "CCC.ObjStor.C02 Enforce Uniform Bucket-level Access to Prevent Inconsistent Permissions", "SubSectionObjective": "Ensure that uniform bucket-level access is enforced across all object storage buckets. This prevents the use of ad-hoc or inconsistent object-level permissions, ensuring centralized, consistent, and secure access management in accordance with the principle of least privilege.", "Applicability": [ @@ -3673,982 +2915,9 @@ "cloudstorage_bucket_uniform_bucket_level_access" ] }, - { - "Id": "CCC.MLDE.CN01.AR01", - "Description": "Verify that only authorized users can access MLDE resources,\nand that access modes are properly defined and enforced.", - "Attributes": [ - { - "FamilyName": "Identity and Access Management", - "FamilyDescription": "TODO: Describe this control family", - "Section": "CCC.MLDE.CN01 Define Access Mode for ML Development Environments", - "SubSection": "", - "SubSectionObjective": "Ensure that access to Machine Learning Development Environment (MLDE)\nresources is strictly defined and controlled.\nOnly authorized users with appropriate permissions can access these environments,\nmitigating the risk of unauthorized access, data leakage, or service disruption.", - "Applicability": [ - "tlp-red", - "tlp-amber", - "tlp-green", - "tlp-clear" - ], - "Recommendation": "", - "SectionThreatMappings": [ - { - "ReferenceId": "CCC", - "Identifiers": [ - "CCC.MLDE.TH01", - "CCC.TH01" - ] - } - ], - "SectionGuidelineMappings": [ - { - "ReferenceId": "NIST-CSF", - "Identifiers": [ - "PR.AC-3" - ] - }, - { - "ReferenceId": "ISO_27001", - "Identifiers": [ - "2013 A.9.1.1", - "2013 A.9.2.1" - ] - }, - { - "ReferenceId": "NIST_800_53", - "Identifiers": [ - "AC-2", - "AC-3" - ] - }, - { - "ReferenceId": "CCM", - "Identifiers": [ - "IAM-01", - "IAM-02" - ] - } - ] - } - ], - "Checks": [ - "iam_account_access_approval_enabled", - "iam_audit_logs_enabled", - "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", - "iam_sa_no_user_managed_keys", - "iam_sa_user_managed_key_rotate_90_days", - "iam_sa_user_managed_key_unused", - "iam_service_account_unused", - "gke_cluster_no_default_service_account", - "compute_instance_default_service_account_in_use", - "compute_instance_default_service_account_in_use_with_full_api_access" - ] - }, - { - "Id": "CCC.MLDE.CN03.AR01", - "Description": "Verify that root access is disabled on MLDE instances containing sensitive data.", - "Attributes": [ - { - "FamilyName": "Identity and Access Management", - "FamilyDescription": "TODO: Describe this control family", - "Section": "CCC.MLDE.CN03 Disable Root Access on MLDE Instances", - "SubSection": "", - "SubSectionObjective": "Prevent users from obtaining root access on MLDE instances to reduce the\nrisk of unauthorized system modifications and potential security breaches.", - "Applicability": [ - "tlp-red" - ], - "Recommendation": "", - "SectionThreatMappings": [ - { - "ReferenceId": "CCC", - "Identifiers": [ - "CCC.MLDE.TH01" - ] - } - ], - "SectionGuidelineMappings": [ - { - "ReferenceId": "NIST-CSF", - "Identifiers": [ - "PR.AC-4" - ] - }, - { - "ReferenceId": "NIST_800_53", - "Identifiers": [ - "AC-6" - ] - }, - { - "ReferenceId": "CCM", - "Identifiers": [ - "IAM-08", - "IAM-12" - ] - }, - { - "ReferenceId": "ISO_27001", - "Identifiers": [ - "2013 A.9.2.3" - ] - } - ] - } - ], - "Checks": [ - "compute_project_os_login_enabled", - "compute_instance_block_project_wide_ssh_keys_disabled", - "compute_firewall_ssh_access_from_the_internet_allowed" - ] - }, - { - "Id": "CCC.MLDE.CN03.AR02", - "Description": "For MLDE instances without sensitive data, ensure that root access is only\nenabled when necessary and properly authorized.", - "Attributes": [ - { - "FamilyName": "Identity and Access Management", - "FamilyDescription": "TODO: Describe this control family", - "Section": "CCC.MLDE.CN03 Disable Root Access on MLDE Instances", - "SubSection": "", - "SubSectionObjective": "Prevent users from obtaining root access on MLDE instances to reduce the\nrisk of unauthorized system modifications and potential security breaches.", - "Applicability": [ - "tlp-red", - "tlp-amber", - "tlp-green", - "tlp-clear" - ], - "Recommendation": "", - "SectionThreatMappings": [ - { - "ReferenceId": "CCC", - "Identifiers": [ - "CCC.MLDE.TH01" - ] - } - ], - "SectionGuidelineMappings": [ - { - "ReferenceId": "NIST-CSF", - "Identifiers": [ - "PR.AC-4" - ] - }, - { - "ReferenceId": "NIST_800_53", - "Identifiers": [ - "AC-6" - ] - }, - { - "ReferenceId": "CCM", - "Identifiers": [ - "IAM-08", - "IAM-12" - ] - }, - { - "ReferenceId": "ISO_27001", - "Identifiers": [ - "2013 A.9.2.3" - ] - } - ] - } - ], - "Checks": [ - "compute_firewall_ssh_access_from_the_internet_allowed", - "compute_firewall_rdp_access_from_the_internet_allowed", - "compute_instance_public_ip", - "compute_instance_block_project_wide_ssh_keys_disabled", - "compute_project_os_login_enabled", - "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_sa_no_administrative_privileges", - "iam_no_service_roles_at_project_level", - "iam_audit_logs_enabled" - ] - }, - { - "Id": "CCC.MLDE.CN04.AR01", - "Description": "Verify that terminal access is disabled on MLDE instances containing sensitive data.", - "Attributes": [ - { - "FamilyName": "Identity and Access Management", - "FamilyDescription": "TODO: Describe this control family", - "Section": "CCC.MLDE.CN04 Disable Terminal Access on MLDE Instances", - "SubSection": "", - "SubSectionObjective": "Prevent users from accessing the terminal on MLDE instances to limit the risk of\nunauthorized commands and potential system compromise.", - "Applicability": [ - "tlp-red" - ], - "Recommendation": "", - "SectionThreatMappings": [ - { - "ReferenceId": "CCC", - "Identifiers": [ - "CCC.MLDE.TH01" - ] - } - ], - "SectionGuidelineMappings": [ - { - "ReferenceId": "NIST-CSF", - "Identifiers": [ - "PR.AC-4" - ] - }, - { - "ReferenceId": "NIST_800_53", - "Identifiers": [ - "AC-6" - ] - }, - { - "ReferenceId": "CCM", - "Identifiers": [ - "IAM-08" - ] - }, - { - "ReferenceId": "ISO_27001", - "Identifiers": [ - "2013 A.9.2.3" - ] - } - ] - } - ], - "Checks": [ - "compute_instance_serial_ports_in_use" - ] - }, - { - "Id": "CCC.MLDE.CN04.AR02", - "Description": "For MLDE instances without sensitive data, ensure that terminal access is only\nenabled when necessary and properly authorized.", - "Attributes": [ - { - "FamilyName": "Identity and Access Management", - "FamilyDescription": "TODO: Describe this control family", - "Section": "CCC.MLDE.CN04 Disable Terminal Access on MLDE Instances", - "SubSection": "", - "SubSectionObjective": "Prevent users from accessing the terminal on MLDE instances to limit the risk of\nunauthorized commands and potential system compromise.", - "Applicability": [ - "tlp-red", - "tlp-amber", - "tlp-green", - "tlp-clear" - ], - "Recommendation": "", - "SectionThreatMappings": [ - { - "ReferenceId": "CCC", - "Identifiers": [ - "CCC.MLDE.TH01" - ] - } - ], - "SectionGuidelineMappings": [ - { - "ReferenceId": "NIST-CSF", - "Identifiers": [ - "PR.AC-4" - ] - }, - { - "ReferenceId": "NIST_800_53", - "Identifiers": [ - "AC-6" - ] - }, - { - "ReferenceId": "CCM", - "Identifiers": [ - "IAM-08" - ] - }, - { - "ReferenceId": "ISO_27001", - "Identifiers": [ - "2013 A.9.2.3" - ] - } - ] - } - ], - "Checks": [ - "compute_firewall_rdp_access_from_the_internet_allowed", - "compute_firewall_ssh_access_from_the_internet_allowed", - "compute_instance_serial_ports_in_use", - "compute_instance_public_ip" - ] - }, - { - "Id": "CCC.MLDE.CN02.AR01", - "Description": "Confirm that file download functionality is disabled on MLDE instances containing sensitive data.", - "Attributes": [ - { - "FamilyName": "Data Protection", - "FamilyDescription": "TODO: Describe this control family", - "Section": "CCC.MLDE.CN02 Disable File Downloads on MLDE Instances", - "SubSection": "", - "SubSectionObjective": "Prevent unauthorized file downloads from MLDE instances to protect sensitive data from being exfiltrated.", - "Applicability": [ - "tlp-red" - ], - "Recommendation": "", - "SectionThreatMappings": [ - { - "ReferenceId": "CCC", - "Identifiers": [ - "CCC.MLDE.TH02", - "CCC.TH02" - ] - } - ], - "SectionGuidelineMappings": [ - { - "ReferenceId": "NIST-CSF", - "Identifiers": [ - "PR.DS-5" - ] - }, - { - "ReferenceId": "CCM", - "Identifiers": [ - "DSI-05", - "DSI-07" - ] - }, - { - "ReferenceId": "ISO_27001", - "Identifiers": [ - "2013 A.13.2.1" - ] - }, - { - "ReferenceId": "NIST_800_53", - "Identifiers": [ - "SC-7", - "SC-8" - ] - } - ] - } - ], - "Checks": [] - }, - { - "Id": "CCC.MLDE.CN02.AR02", - "Description": "For MLDE instances without sensitive data, ensure that file downloads are monitored and logged.", - "Attributes": [ - { - "FamilyName": "Data Protection", - "FamilyDescription": "TODO: Describe this control family", - "Section": "", - "SubSection": "CCC.MLDE.CN02 Disable File Downloads on MLDE Instances", - "SubSectionObjective": "Prevent unauthorized file downloads from MLDE instances to protect sensitive data from being exfiltrated.", - "Applicability": [ - "tlp-red", - "tlp-amber", - "tlp-green", - "tlp-clear" - ], - "Recommendation": "", - "SectionThreatMappings": [ - { - "ReferenceId": "CCC", - "Identifiers": [ - "CCC.MLDE.TH02", - "CCC.TH02" - ] - } - ], - "SectionGuidelineMappings": [ - { - "ReferenceId": "NIST-CSF", - "Identifiers": [ - "PR.DS-5" - ] - }, - { - "ReferenceId": "CCM", - "Identifiers": [ - "DSI-05", - "DSI-07" - ] - }, - { - "ReferenceId": "ISO_27001", - "Identifiers": [ - "2013 A.13.2.1" - ] - }, - { - "ReferenceId": "NIST_800_53", - "Identifiers": [ - "SC-7", - "SC-8" - ] - } - ] - } - ], - "Checks": [ - "iam_audit_logs_enabled", - "logging_sink_created", - "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_custom_role_changes_enabled", - "logging_log_metric_filter_and_alert_for_sql_instance_configuration_changes_enabled", - "logging_log_metric_filter_and_alert_for_vpc_network_changes_enabled", - "logging_log_metric_filter_and_alert_for_vpc_firewall_rule_changes_enabled", - "logging_log_metric_filter_and_alert_for_vpc_network_route_changes_enabled", - "logging_log_metric_filter_and_alert_for_project_ownership_changes_enabled" - ] - }, - { - "Id": "CCC.MLDE.CN05.AR01", - "Description": "Verify that only approved VM and container images can be selected when creating MLDE instances.", - "Attributes": [ - { - "FamilyName": "Configuration Management", - "FamilyDescription": "TODO: Describe this control family", - "Section": "", - "SubSection": "CCC.MLDE.CN05 Restrict Environment Options on MLDE Instances", - "SubSectionObjective": "Limit the virtual machine and container image options available when creating\nnew MLDE instances to approved and secure configurations.", - "Applicability": [ - "tlp-red", - "tlp-amber" - ], - "Recommendation": "", - "SectionThreatMappings": [ - { - "ReferenceId": "CCC", - "Identifiers": [ - "CCC.MLDE.TH04" - ] - } - ], - "SectionGuidelineMappings": [ - { - "ReferenceId": "NIST-CSF", - "Identifiers": [ - "PR.IP-1" - ] - }, - { - "ReferenceId": "CCM", - "Identifiers": [ - "TVM-02" - ] - }, - { - "ReferenceId": "ISO_27001", - "Identifiers": [ - "2013 A.12.5.1" - ] - }, - { - "ReferenceId": "NIST_800_53", - "Identifiers": [ - "CM-2" - ] - } - ] - } - ], - "Checks": [ - "artifacts_container_analysis_enabled", - "gcr_container_scanning_enabled" - ] - }, - { - "Id": "CCC.MLDE.CN05.AR02", - "Description": "Attempt to create an MLDE instance with an unapproved image and confirm that it is denied.", - "Attributes": [ - { - "FamilyName": "Configuration Management", - "FamilyDescription": "TODO: Describe this control family", - "Section": "", - "SubSection": "CCC.MLDE.CN05 Restrict Environment Options on MLDE Instances", - "SubSectionObjective": "Limit the virtual machine and container image options available when creating\nnew MLDE instances to approved and secure configurations.", - "Applicability": [ - "tlp-red" - ], - "Recommendation": "", - "SectionThreatMappings": [ - { - "ReferenceId": "CCC", - "Identifiers": [ - "CCC.MLDE.TH04" - ] - } - ], - "SectionGuidelineMappings": [ - { - "ReferenceId": "NIST-CSF", - "Identifiers": [ - "PR.IP-1" - ] - }, - { - "ReferenceId": "CCM", - "Identifiers": [ - "TVM-02" - ] - }, - { - "ReferenceId": "ISO_27001", - "Identifiers": [ - "2013 A.12.5.1" - ] - }, - { - "ReferenceId": "NIST_800_53", - "Identifiers": [ - "CM-2" - ] - } - ] - } - ], - "Checks": [ - "artifacts_container_analysis_enabled", - "gcr_container_scanning_enabled", - "compute_instance_shielded_vm_enabled", - "compute_instance_confidential_computing_enabled", - "compute_instance_public_ip", - "compute_instance_ip_forwarding_is_enabled", - "compute_instance_default_service_account_in_use", - "compute_instance_serial_ports_in_use", - "compute_instance_block_project_wide_ssh_keys_disabled", - "compute_instance_encryption_with_csek_enabled", - "compute_firewall_ssh_access_from_the_internet_allowed", - "compute_firewall_rdp_access_from_the_internet_allowed" - ] - }, - { - "Id": "CCC.MLDE.CN06.AR01", - "Description": "Verify that automatic scheduled upgrades are enabled on user-managed\nMLDE instances containing sensitive data.", - "Attributes": [ - { - "FamilyName": "Vulnerability Management", - "FamilyDescription": "TODO: Describe this control family", - "Section": "", - "SubSection": "CCC.MLDE.CN06 Require Automatic Scheduled Upgrades on User-Managed MLDE Instances", - "SubSectionObjective": "Ensure that MLDE instances are kept up-to-date with the\nlatest security patches by enforcing automatic scheduled upgrades.", - "Applicability": [ - "tlp-red" - ], - "Recommendation": "", - "SectionThreatMappings": [ - { - "ReferenceId": "CCC", - "Identifiers": [ - "CCC.MLDE.TH04", - "CCC.TH06" - ] - } - ], - "SectionGuidelineMappings": [ - { - "ReferenceId": "NIST-CSF", - "Identifiers": [ - "PR.IP-12" - ] - }, - { - "ReferenceId": "CCM", - "Identifiers": [ - "TVM-01", - "TVM-02" - ] - }, - { - "ReferenceId": "ISO_27001", - "Identifiers": [ - "2013 A.12.6.1" - ] - }, - { - "ReferenceId": "NIST_800_53", - "Identifiers": [ - "SI-2" - ] - } - ] - } - ], - "Checks": [ - "artifacts_container_analysis_enabled", - "gcr_container_scanning_enabled" - ] - }, - { - "Id": "CCC.MLDE.CN06.AR02", - "Description": "Ensure that the upgrade schedule is appropriately configured and\ndoes not interfere with critical operations.", - "Attributes": [ - { - "FamilyName": "Vulnerability Management", - "FamilyDescription": "TODO: Describe this control family", - "Section": "", - "SubSection": "CCC.MLDE.CN06 Require Automatic Scheduled Upgrades on User-Managed MLDE Instances", - "SubSectionObjective": "Ensure that MLDE instances are kept up-to-date with the\nlatest security patches by enforcing automatic scheduled upgrades.", - "Applicability": [ - "tlp-red", - "tlp-amber", - "tlp-green", - "tlp-clear" - ], - "Recommendation": "", - "SectionThreatMappings": [ - { - "ReferenceId": "CCC", - "Identifiers": [ - "CCC.MLDE.TH04", - "CCC.TH06" - ] - } - ], - "SectionGuidelineMappings": [ - { - "ReferenceId": "NIST-CSF", - "Identifiers": [ - "PR.IP-12" - ] - }, - { - "ReferenceId": "CCM", - "Identifiers": [ - "TVM-01", - "TVM-02" - ] - }, - { - "ReferenceId": "ISO_27001", - "Identifiers": [ - "2013 A.12.6.1" - ] - }, - { - "ReferenceId": "NIST_800_53", - "Identifiers": [ - "SI-2" - ] - } - ] - } - ], - "Checks": [] - }, - { - "Id": "CCC.MLDE.CN07.AR01", - "Description": "Verify that MLDE instances containing sensitive data cannot be accessed via public IP addresses.", - "Attributes": [ - { - "FamilyName": "Network Security", - "FamilyDescription": "TODO: Describe this control family", - "Section": "", - "SubSection": "CCC.MLDE.CN07 Restrict Public IP Access on MLDE Instances", - "SubSectionObjective": "Prevent public IP access to MLDE instances to reduce exposure to the internet and enhance security.", - "Applicability": [ - "tlp-red" - ], - "Recommendation": "", - "SectionThreatMappings": [ - { - "ReferenceId": "CCC", - "Identifiers": [ - "CCC.MLDE.TH02", - "CCC.VPC.TH02" - ] - } - ], - "SectionGuidelineMappings": [ - { - "ReferenceId": "NIST-CSF", - "Identifiers": [ - "PR.AC-3" - ] - }, - { - "ReferenceId": "CCM", - "Identifiers": [ - "SEF-05" - ] - }, - { - "ReferenceId": "ISO_27001", - "Identifiers": [ - "2013 A.13.1.1" - ] - }, - { - "ReferenceId": "NIST_800_53", - "Identifiers": [ - "SC-7" - ] - } - ] - } - ], - "Checks": [ - "compute_instance_public_ip", - "compute_firewall_rdp_access_from_the_internet_allowed", - "compute_firewall_ssh_access_from_the_internet_allowed" - ] - }, - { - "Id": "CCC.MLDE.CN07.AR02", - "Description": "For MLDE instances without sensitive data requiring public access,\nensure that appropriate security controls are in place and access is approved.", - "Attributes": [ - { - "FamilyName": "Network Security", - "FamilyDescription": "TODO: Describe this control family", - "Section": "CCC.MLDE.CN07 Restrict Public IP Access on MLDE Instances", - "SubSection": "", - "SubSectionObjective": "Prevent public IP access to MLDE instances to reduce exposure to the internet and enhance security.", - "Applicability": [ - "tlp-red", - "tlp-amber", - "tlp-green", - "tlp-clear" - ], - "Recommendation": "", - "SectionThreatMappings": [ - { - "ReferenceId": "CCC", - "Identifiers": [ - "CCC.MLDE.TH02", - "CCC.VPC.TH02" - ] - } - ], - "SectionGuidelineMappings": [ - { - "ReferenceId": "NIST-CSF", - "Identifiers": [ - "PR.AC-3" - ] - }, - { - "ReferenceId": "CCM", - "Identifiers": [ - "SEF-05" - ] - }, - { - "ReferenceId": "ISO_27001", - "Identifiers": [ - "2013 A.13.1.1" - ] - }, - { - "ReferenceId": "NIST_800_53", - "Identifiers": [ - "SC-7" - ] - } - ] - } - ], - "Checks": [ - "compute_instance_public_ip", - "compute_firewall_rdp_access_from_the_internet_allowed", - "compute_firewall_ssh_access_from_the_internet_allowed", - "cloudsql_instance_public_ip", - "cloudsql_instance_private_ip_assignment", - "cloudsql_instance_public_access" - ] - }, - { - "Id": "CCC.MLDE.CN08.AR01", - "Description": "Verify that MLDE instances containing sensitive data can only be deployed in\napproved virtual networks with appropriate security controls.", - "Attributes": [ - { - "FamilyName": "Network Security", - "FamilyDescription": "TODO: Describe this control family", - "Section": "CCC.MLDE.CN08 Restrict Virtual Networks for MLDE Instances", - "SubSection": "", - "SubSectionObjective": "Limit the virtual networks that can be used when creating new MLDE instances to\nensure they are deployed within approved and secure network environments.", - "Applicability": [ - "tlp-red" - ], - "Recommendation": "", - "SectionThreatMappings": [ - { - "ReferenceId": "CCC", - "Identifiers": [ - "CCC.MLDE.TH01", - "CCC.TH01" - ] - } - ], - "SectionGuidelineMappings": [ - { - "ReferenceId": "NIST-CSF", - "Identifiers": [ - "PR.AC-4" - ] - }, - { - "ReferenceId": "CCM", - "Identifiers": [ - "IAM-12" - ] - }, - { - "ReferenceId": "ISO_27001", - "Identifiers": [ - "2013 A.9.1.2" - ] - }, - { - "ReferenceId": "NIST_800_53", - "Identifiers": [ - "AC-6" - ] - } - ] - } - ], - "Checks": [ - "compute_network_default_in_use", - "compute_network_not_legacy", - "compute_firewall_rdp_access_from_the_internet_allowed", - "compute_firewall_ssh_access_from_the_internet_allowed", - "compute_instance_public_ip", - "cloudsql_instance_public_ip", - "cloudsql_instance_private_ip_assignment", - "cloudsql_instance_public_access" - ] - }, - { - "Id": "CCC.MLDE.CN08.AR02", - "Description": "Ensure that MLDE instances without sensitive data are deployed in\nnetworks that meet organizational security standards.", - "Attributes": [ - { - "FamilyName": "Network Security", - "FamilyDescription": "TODO: Describe this control family", - "Section": "CCC.MLDE.CN08 Restrict Virtual Networks for MLDE Instances", - "SubSection": "", - "SubSectionObjective": "Limit the virtual networks that can be used when creating new MLDE instances to\nensure they are deployed within approved and secure network environments.", - "Applicability": [ - "tlp-red", - "tlp-amber", - "tlp-green", - "tlp-clear" - ], - "Recommendation": "", - "SectionThreatMappings": [ - { - "ReferenceId": "CCC", - "Identifiers": [ - "CCC.MLDE.TH01", - "CCC.TH01" - ] - } - ], - "SectionGuidelineMappings": [ - { - "ReferenceId": "NIST-CSF", - "Identifiers": [ - "PR.AC-4" - ] - }, - { - "ReferenceId": "CCM", - "Identifiers": [ - "IAM-12" - ] - }, - { - "ReferenceId": "ISO_27001", - "Identifiers": [ - "2013 A.9.1.2" - ] - }, - { - "ReferenceId": "NIST_800_53", - "Identifiers": [ - "AC-6" - ] - } - ] - } - ], - "Checks": [ - "compute_firewall_rdp_access_from_the_internet_allowed", - "compute_firewall_ssh_access_from_the_internet_allowed", - "compute_network_not_legacy", - "compute_network_default_in_use", - "compute_instance_public_ip", - "compute_instance_ip_forwarding_is_enabled", - "compute_instance_shielded_vm_enabled", - "compute_instance_serial_ports_in_use", - "cloudsql_instance_private_ip_assignment", - "cloudsql_instance_public_ip", - "cloudsql_instance_public_access", - "cloudstorage_bucket_public_access" - ] - }, - { - "Id": "CCC.Message.CN01.AR01", - "Description": "Attempt to publish a message without using a customer-managed encryption key\nand verify that the message is rejected or not stored.", - "Attributes": [ - { - "FamilyName": "Encryption", - "FamilyDescription": "TODO: Describe this control family", - "Section": "CCC.Message.CN01 Use Customer-Managed Encryption Keys (CMEK) for Messages", - "SubSection": "", - "SubSectionObjective": "Ensure that messages are encrypted using customer-managed encryption keys (CMEK)\nto provide enhanced control over encryption processes and keys, meeting compliance and security requirements.", - "Applicability": [ - "tlp-clear", - "tlp-green", - "tlp-amber", - "tlp-red" - ], - "Recommendation": "", - "SectionThreatMappings": [ - { - "ReferenceId": "CCC", - "Identifiers": [ - "CCC.TH01" - ] - } - ], - "SectionGuidelineMappings": [ - { - "ReferenceId": "NIST-CSF", - "Identifiers": [ - "PR.DS-1" - ] - }, - { - "ReferenceId": "NIST_800_53", - "Identifiers": [ - "SC-12", - "SC-13" - ] - } - ] - } - ], - "Checks": [ - "dataproc_encrypted_with_cmks_disabled", - "compute_instance_encryption_with_csek_enabled", - "bigquery_dataset_cmk_encryption", - "bigquery_table_cmk_encryption", - "kms_key_not_publicly_accessible", - "kms_key_rotation_enabled" - ] - }, { "Id": "CCC.Monitor.CN01.AR01", - "Description": "When an External Monitoring system exceeds the anticipated rate of monitoring checks then\nRate Limiting MUST be applied and an Audit Alert MUST be generated.", + "Description": "When an External Monitoring system exceeds the anticipated rate of monitoring checks then Rate Limiting MUST be applied and an Audit Alert MUST be generated.", "Attributes": [ { "FamilyName": "Logging & Monitoring", @@ -4705,7 +2974,7 @@ }, { "Id": "CCC.Monitor.CN02.AR01", - "Description": "When an Custom or User-Defined Metric starts to flood a collector, then a rate limit MUST be applied\nto reduce the network impact of traffic and an alert must triggered.", + "Description": "When an Custom or User-Defined Metric starts to flood a collector, then a rate limit MUST be applied to reduce the network impact of traffic and an alert must triggered.", "Attributes": [ { "FamilyName": "Logging & Monitoring", @@ -4764,14 +3033,14 @@ }, { "Id": "CCC.Monitor.CN03.AR01", - "Description": "When external systems have approved access to internal systems not normally available for public access\nthen they MUST be secured to prevent unauthorised access jumping through to the internal systems and\nonly allow access to specific internal services.", + "Description": "When external systems have approved access to internal systems not normally available for public access then they MUST be secured to prevent unauthorised access jumping through to the internal systems and only allow access to specific internal services.", "Attributes": [ { "FamilyName": "Identity and Access Management", "FamilyDescription": "Controls designed to prevent unauthorised access to monitoring features.", "Section": "CCC.Monitor.CN03 Access External Monitoring", "SubSection": "", - "SubSectionObjective": "Control access to Synthetic monitoring solutions using API keys or Certificate based authentication to\nensure they don't become an attack path, preventing monitoring systems from forging network requests to\ngain access to internal systems.", + "SubSectionObjective": "Control access to Synthetic monitoring solutions using API keys or Certificate based authentication to ensure they don't become an attack path, preventing monitoring systems from forging network requests to gain access to internal systems.", "Applicability": [ "tlp-clear", "tlp-green", @@ -4813,7 +3082,7 @@ }, { "Id": "CCC.Monitor.CN04.AR01", - "Description": "When monitoring dashboards display degraded services which may become potential targets then the\ndashboard MUST be protected from unauthorised access.", + "Description": "When monitoring dashboards display degraded services which may become potential targets then the dashboard MUST be protected from unauthorised access.", "Attributes": [ { "FamilyName": "Identity and Access Management", @@ -4858,7 +3127,7 @@ }, { "Id": "CCC.Monitor.CN05.AR01", - "Description": "When monitoring services have generated an alert, the service MUST ensure only authorised\nresponders silence or acknowledge the alert.", + "Description": "When monitoring services have generated an alert, the service MUST ensure only authorised responders silence or acknowledge the alert.", "Attributes": [ { "FamilyName": "Identity and Access Management", @@ -4920,7 +3189,7 @@ "FamilyDescription": "Controls designed to prevent unauthorised access to monitoring features.", "Section": "CCC.Monitor.CN06 Metrics pushed for authorised services only", "SubSection": "", - "SubSectionObjective": "Use IAM to control which types of metrics or traces can be pushed by different system to avoid a compromised\nsystem pushing fabricated metrics about a different service", + "SubSectionObjective": "Use IAM to control which types of metrics or traces can be pushed by different system to avoid a compromised system pushing fabricated metrics about a different service", "Applicability": [ "tlp-clear", "tlp-green", @@ -4964,199 +3233,16 @@ "iam_service_account_unused" ] }, - { - "Id": "CCC.SecMgmt.CN01.AR01", - "Description": "Attempt to use an outdated version of a secret after its rotation period\nhas passed and verify that access is denied.", - "Attributes": [ - { - "FamilyName": "Data Protection", - "FamilyDescription": "TODO: Describe this control family", - "Section": "CCC.SecMgmt.CN01 Enforce Automatic Secret Rotation", - "SubSection": "", - "SubSectionObjective": "Ensure that secrets are automatically rotated on a defined schedule to\nreduce the risk of secret compromise and unauthorized access.", - "Applicability": [ - "tlp-red", - "tlp-amber" - ], - "Recommendation": "", - "SectionThreatMappings": [ - { - "ReferenceId": "CCC", - "Identifiers": [ - "CCC.TH01", - "CCC.TH14" - ] - } - ], - "SectionGuidelineMappings": [ - { - "ReferenceId": "NIST-CSF", - "Identifiers": [ - "PR.DS-6" - ] - }, - { - "ReferenceId": "NIST_800_53", - "Identifiers": [ - "SC-12", - "SC-28" - ] - } - ] - } - ], - "Checks": [ - "apikeys_key_rotated_in_90_days", - "iam_sa_user_managed_key_rotate_90_days", - "kms_key_rotation_enabled" - ] - }, - { - "Id": "CCC.SecMgmt.CN02.AR01", - "Description": "Attempt to retrieve a secret from an unauthorized region and verify that access is denied.", - "Attributes": [ - { - "FamilyName": "Data Protection", - "FamilyDescription": "TODO: Describe this control family", - "Section": "CCC.SecMgmt.CN02 Enforce Secret Replication Policies", - "SubSection": "", - "SubSectionObjective": "Ensure that secrets are replicated only to authorized locations as per\norganizational data residency and compliance requirements.", - "Applicability": [ - "tlp-red", - "tlp-amber" - ], - "Recommendation": "", - "SectionThreatMappings": [ - { - "ReferenceId": "CCC", - "Identifiers": [ - "CCC.TH03", - "CCC.TH04" - ] - } - ], - "SectionGuidelineMappings": [ - { - "ReferenceId": "NIST-CSF", - "Identifiers": [ - "PR.DS-5" - ] - }, - { - "ReferenceId": "NIST_800_53", - "Identifiers": [ - "AC-3", - "SC-7" - ] - } - ] - } - ], - "Checks": [] - }, - { - "Id": "CCC.SvlsComp.CN01.AR01", - "Description": "Attempt to access the serverless function over the public internet and verify that access is denied.", - "Attributes": [ - { - "FamilyName": "Network Security", - "FamilyDescription": "TODO: Describe this control family", - "Section": "CCC.SvlsComp.CN01 Enforce Use of Private Endpoints for Serverless Function", - "SubSection": "", - "SubSectionObjective": "Ensure that the serverless function is accessible only through a private endpoint,\nallowing it to communicate securely within a virtual private network and preventing\nunauthorized external access.", - "Applicability": [ - "tlp-red", - "tlp-amber" - ], - "Recommendation": "", - "SectionThreatMappings": [ - { - "ReferenceId": "CCC", - "Identifiers": [ - "CCC.TH01" - ] - } - ], - "SectionGuidelineMappings": [ - { - "ReferenceId": "NIST-CSF", - "Identifiers": [ - "PR.AC-5" - ] - }, - { - "ReferenceId": "NIST_800_53", - "Identifiers": [ - "SC-7", - "SC-8" - ] - } - ] - } - ], - "Checks": [ - "compute_firewall_rdp_access_from_the_internet_allowed", - "compute_firewall_ssh_access_from_the_internet_allowed", - "compute_instance_public_ip", - "cloudsql_instance_public_ip", - "cloudsql_instance_public_access", - "cloudsql_instance_private_ip_assignment", - "cloudstorage_bucket_public_access", - "bigquery_dataset_public_access", - "compute_public_address_shodan" - ] - }, - { - "Id": "CCC.SvlsComp.CN02.AR01", - "Description": "Send requests to invoke the function up to the allowed threshold and confirm they\nare successful; then send additional requests exceeding the threshold from the same\nentity and verify that they are denied.", - "Attributes": [ - { - "FamilyName": "Availability", - "FamilyDescription": "TODO: Describe this control family", - "Section": "CCC.SvlsComp.CN02 Implement Function Invocation Rate Limits", - "SubSection": "", - "SubSectionObjective": "Ensure that function invocation is limited to a specified threshold from any single entity,\npreventing resource exhaustion and denial of service attacks.", - "Applicability": [ - "tlp-red", - "tlp-amber" - ], - "Recommendation": "", - "SectionThreatMappings": [ - { - "ReferenceId": "CCC", - "Identifiers": [ - "CCC.TH12" - ] - } - ], - "SectionGuidelineMappings": [ - { - "ReferenceId": "NIST-CSF", - "Identifiers": [ - "PR.DS-4" - ] - }, - { - "ReferenceId": "NIST_800_53", - "Identifiers": [ - "SC-5" - ] - } - ] - } - ], - "Checks": [] - }, { "Id": "CCC.VPC.CN01.AR01", - "Description": "When a subscription is created, the subscription MUST NOT\ncontain default network resources.", + "Description": "When a subscription is created, the subscription MUST NOT contain default network resources.", "Attributes": [ { "FamilyName": "Network Security", "FamilyDescription": "TODO: Describe this control family", "Section": "CCC.VPC.CN01 Restrict Default Network Creation", "SubSection": "", - "SubSectionObjective": "Restrict the automatic creation of default virtual networks and related\nresources during subscription initialization to avoid insecure default\nconfigurations and enforce custom network policies.", + "SubSectionObjective": "Restrict the automatic creation of default virtual networks and related resources during subscription initialization to avoid insecure default configurations and enforce custom network policies.", "Applicability": [ "tlp-amber", "tlp-red" @@ -5202,74 +3288,16 @@ "compute_network_default_in_use" ] }, - { - "Id": "CCC.VPC.CN02.AR01", - "Description": "When a resource is created in a public subnet, that resource\nMUST NOT be assigned an external IP address by default.", - "Attributes": [ - { - "FamilyName": "Network Security", - "FamilyDescription": "TODO: Describe this control family", - "Section": "CCC.VPC.CN02 Limit Resource Creation in Public Subnet", - "SubSection": "", - "SubSectionObjective": "Restrict the creation of resources in the public subnet with\ndirect access to the internet to minimize attack surfaces.", - "Applicability": [ - "tlp-red" - ], - "Recommendation": "", - "SectionThreatMappings": [ - { - "ReferenceId": "CCC", - "Identifiers": [ - "CCC.VPC.TH02" - ] - } - ], - "SectionGuidelineMappings": [ - { - "ReferenceId": "NIST-CSF", - "Identifiers": [ - "PR.AC-3" - ] - }, - { - "ReferenceId": "CCM", - "Identifiers": [ - "SEF-05" - ] - }, - { - "ReferenceId": "ISO_27001", - "Identifiers": [ - "2013 A.13.1.1" - ] - }, - { - "ReferenceId": "NIST_800_53", - "Identifiers": [ - "AC-4" - ] - } - ] - } - ], - "Checks": [ - "compute_firewall_rdp_access_from_the_internet_allowed", - "compute_firewall_ssh_access_from_the_internet_allowed", - "compute_instance_public_ip", - "cloudsql_instance_public_ip", - "cloudsql_instance_public_access" - ] - }, { "Id": "CCC.VPC.CN03.AR01", - "Description": "When a VPC peering connection is requested, the service MUST\nprevent connections from VPCs that are not explicitly\nallowed.", + "Description": "When a VPC peering connection is requested, the service MUST prevent connections from VPCs that are not explicitly allowed.", "Attributes": [ { "FamilyName": "Network Security", "FamilyDescription": "TODO: Describe this control family", "Section": "CCC.VPC.CN03 Restrict VPC Peering to Authorized Accounts", "SubSection": "", - "SubSectionObjective": "Ensure VPC peering connections are only established with explicitly\nauthorized destinations to limit network exposure and enforce boundary\ncontrols.", + "SubSectionObjective": "Ensure VPC peering connections are only established with explicitly authorized destinations to limit network exposure and enforce boundary controls.", "Applicability": [ "tlp-green", "tlp-amber", @@ -5316,14 +3344,14 @@ }, { "Id": "CCC.VPC.CN04.AR01", - "Description": "When any network traffic goes to or from an interface in the VPC,\nthe service MUST capture and log all relevant information.", + "Description": "When any network traffic goes to or from an interface in the VPC, the service MUST capture and log all relevant information.", "Attributes": [ { "FamilyName": "Network Security", "FamilyDescription": "TODO: Describe this control family", "Section": "CCC.VPC.CN04 Enforce VPC Flow Logs on VPCs", "SubSection": "", - "SubSectionObjective": "Ensure VPCs are configured with flow logs enabled to capture traffic\ninformation.", + "SubSectionObjective": "Ensure VPCs are configured with flow logs enabled to capture traffic information.", "Applicability": [ "tlp-amber", "tlp-red" @@ -5371,14 +3399,14 @@ }, { "Id": "CCC.Vector.CN01.AR01", - "Description": "When a vector embedding is submitted for indexing, the system MUST validate that it\nmatches expected schema, dimension, and format profiles.", + "Description": "When a vector embedding is submitted for indexing, the system MUST validate that it matches expected schema, dimension, and format profiles.", "Attributes": [ { "FamilyName": "Vector Indexing", "FamilyDescription": "Controls specific to the management and protection of vector embedding and index operations.", "Section": "CCC.Vector.CN01 Validate Embeddings Before Indexing", "SubSection": "", - "SubSectionObjective": "Ensure all incoming embeddings are structurally and statistically validated\nbefore indexing to prevent poisoning or corruption.", + "SubSectionObjective": "Ensure all incoming embeddings are structurally and statistically validated before indexing to prevent poisoning or corruption.", "Applicability": [ "tlp-clear", "tlp-green", @@ -5410,14 +3438,14 @@ }, { "Id": "CCC.Vector.CN02.AR01", - "Description": "When an index lifecycle event is triggered, the service MUST\nverify that the actor has explicit permissions for the operation type.", + "Description": "When an index lifecycle event is triggered, the service MUST verify that the actor has explicit permissions for the operation type.", "Attributes": [ { "FamilyName": "Vector Indexing", "FamilyDescription": "Controls specific to the management and protection of vector embedding and index operations.", "Section": "CCC.Vector.CN02 Enforce Role-Based Index Lifecycle Management", "SubSection": "", - "SubSectionObjective": "Restrict index lifecycle operations (create, delete, rollback) to privileged\nidentities using fine-grained access controls.", + "SubSectionObjective": "Restrict index lifecycle operations (create, delete, rollback) to privileged identities using fine-grained access controls.", "Applicability": [ "tlp-clear", "tlp-green", @@ -5455,14 +3483,14 @@ }, { "Id": "CCC.Vector.CN03.AR01", - "Description": "When a metadata filter is applied to a query, the service MUST\nverify the requester is authorized to access that field.", + "Description": "When a metadata filter is applied to a query, the service MUST verify the requester is authorized to access that field.", "Attributes": [ { "FamilyName": "Vector Indexing", "FamilyDescription": "Controls specific to the management and protection of vector embedding and index operations.", "Section": "CCC.Vector.CN03 Enforce Metadata-Level Access Controls", "SubSection": "", - "SubSectionObjective": "Apply access control policies to metadata fields used in filtering to\nprevent unauthorized exposure or inference.", + "SubSectionObjective": "Apply access control policies to metadata fields used in filtering to prevent unauthorized exposure or inference.", "Applicability": [ "tlp-amber", "tlp-red" @@ -5489,28 +3517,18 @@ ] } ], - "Checks": [ - "iam_audit_logs_enabled", - "iam_account_access_approval_enabled", - "iam_no_service_roles_at_project_level", - "iam_role_sa_enforce_separation_of_duties", - "iam_sa_no_administrative_privileges", - "cloudstorage_bucket_public_access", - "cloudstorage_bucket_uniform_bucket_level_access", - "iam_cloud_asset_inventory_enabled", - "compute_instance_default_service_account_in_use" - ] + "Checks": [] }, { "Id": "CCC.Vector.CN04.AR01", - "Description": "When ingestion exceeds pre-defined thresholds, the service MUST\nthrottle or reject excess vector write operations.", + "Description": "When ingestion exceeds pre-defined thresholds, the service MUST throttle or reject excess vector write operations.", "Attributes": [ { "FamilyName": "Vector Indexing", "FamilyDescription": "Controls specific to the management and protection of vector embedding and index operations.", "Section": "CCC.Vector.CN04 Enforce Ingestion Quotas and Throttling", "SubSection": "", - "SubSectionObjective": "Prevent ingestion-based DoS or index pollution by\nrate-limiting vector submissions and enforcing quotas.", + "SubSectionObjective": "Prevent ingestion-based DoS or index pollution by rate-limiting vector submissions and enforcing quotas.", "Applicability": [ "tlp-green", "tlp-amber", @@ -5540,14 +3558,14 @@ }, { "Id": "CCC.Vector.CN05.AR01", - "Description": "When a rollback is attempted, the system MUST log\nthe action and verify rollback authorization.", + "Description": "When a rollback is attempted, the system MUST log the action and verify rollback authorization.", "Attributes": [ { "FamilyName": "Vector Indexing", "FamilyDescription": "Controls specific to the management and protection of vector embedding and index operations.", "Section": "CCC.Vector.CN05 Enforce Index Versioning with Rollback Protection", "SubSection": "", - "SubSectionObjective": "Ensure vector indexes are versioned and that rollback\noperations are authorized and auditable.", + "SubSectionObjective": "Ensure vector indexes are versioned and that rollback operations are authorized and auditable.", "Applicability": [ "tlp-amber", "tlp-red" @@ -5588,14 +3606,14 @@ }, { "Id": "CCC.Vector.CN06.AR01", - "Description": "When an embedding is submitted, the service MUST validate\nthat its format and dimensionality match allowed profiles.", + "Description": "When an embedding is submitted, the service MUST validate that its format and dimensionality match allowed profiles.", "Attributes": [ { "FamilyName": "Vector Indexing", "FamilyDescription": "Controls specific to the management and protection of vector embedding and index operations.", "Section": "CCC.Vector.CN06 Enforce Dimensional and Format Constraints", "SubSection": "", - "SubSectionObjective": "Reject embeddings that do not conform to expected model\nspecifications (dimensions, format, etc).", + "SubSectionObjective": "Reject embeddings that do not conform to expected model specifications (dimensions, format, etc).", "Applicability": [ "tlp-clear", "tlp-green", @@ -5626,14 +3644,14 @@ }, { "Id": "CCC.Vector.CN07.AR01", - "Description": "When a search request is issued, clients MUST be allowed\nto declare their requirement for exact vs approximate results.", + "Description": "When a search request is issued, clients MUST be allowed to declare their requirement for exact vs approximate results.", "Attributes": [ { "FamilyName": "Vector Indexing", "FamilyDescription": "Controls specific to the management and protection of vector embedding and index operations.", "Section": "CCC.Vector.CN07 Support Explicit ANN vs. Exact Search Configuration", "SubSection": "", - "SubSectionObjective": "Provide clients with the option to enforce exact-match\n(non-ANN) search where search fidelity is critical.", + "SubSectionObjective": "Provide clients with the option to enforce exact-match (non-ANN) search where search fidelity is critical.", "Applicability": [ "tlp-amber", "tlp-red" @@ -5654,20 +3672,20 @@ }, { "Id": "CCC.Core.CN01.AR01", - "Description": "When a port is exposed for non-SSH network traffic, all traffic\nMUST include a TLS handshake AND be encrypted using TLS 1.3 or\nhigher.", + "Description": "When a port is exposed for non-SSH network traffic, all traffic MUST include a TLS handshake AND be encrypted using TLS 1.3 or higher.", "Attributes": [ { "FamilyName": "Data", - "FamilyDescription": "The Data control family ensures the confidentiality, integrity,\navailability, and sovereignty of data across its lifecycle.\nThese controls govern how data is transmitted, stored,\nreplicated, and protected from unauthorized access, tampering,\nor exposure beyond defined trust perimeters.\n", + "FamilyDescription": "The Data control family ensures the confidentiality, integrity, availability, and sovereignty of data across its lifecycle. These controls govern how data is transmitted, stored, replicated, and protected from unauthorized access, tampering, or exposure beyond defined trust perimeters. ", "Section": "CCC.Core.CN01 Encrypt Data for Transmission", "SubSection": "", - "SubSectionObjective": "Ensure that all communications are encrypted in transit to protect\ndata integrity and confidentiality.", + "SubSectionObjective": "Ensure that all communications are encrypted in transit to protect data integrity and confidentiality.", "Applicability": [ "tlp-green", "tlp-amber", "tlp-red" ], - "Recommendation": "Most cloud services enable TLS 1.3 by default. Where it is not\nalready set, ensure that your services are configured or updated\naccordingly.\n", + "Recommendation": "Most cloud services enable TLS 1.3 by default. Where it is not already set, ensure that your services are configured or updated accordingly. ", "SectionThreatMappings": [ { "ReferenceId": "CCC", @@ -5714,21 +3732,21 @@ }, { "Id": "CCC.Core.CN01.AR02", - "Description": "When a port is exposed for SSH network traffic, all traffic MUST\ninclude a SSH handshake AND be encrypted using SSHv2 or higher.", + "Description": "When a port is exposed for SSH network traffic, all traffic MUST include a SSH handshake AND be encrypted using SSHv2 or higher.", "Attributes": [ { "FamilyName": "Data", - "FamilyDescription": "The Data control family ensures the confidentiality, integrity,\navailability, and sovereignty of data across its lifecycle.\nThese controls govern how data is transmitted, stored,\nreplicated, and protected from unauthorized access, tampering,\nor exposure beyond defined trust perimeters.\n", + "FamilyDescription": "The Data control family ensures the confidentiality, integrity, availability, and sovereignty of data across its lifecycle. These controls govern how data is transmitted, stored, replicated, and protected from unauthorized access, tampering, or exposure beyond defined trust perimeters. ", "Section": "CCC.Core.CN01 Encrypt Data for Transmission", "SubSection": "", - "SubSectionObjective": "Ensure that all communications are encrypted in transit to protect\ndata integrity and confidentiality.", + "SubSectionObjective": "Ensure that all communications are encrypted in transit to protect data integrity and confidentiality.", "Applicability": [ "tlp-clear", "tlp-green", "tlp-amber", "tlp-red" ], - "Recommendation": "Any time port 22 is exposed, ensure that it has a properly\nimplemented SSH server with SSHv2 enabled and configured with\nstrong ciphers.\n", + "Recommendation": "Any time port 22 is exposed, ensure that it has a properly implemented SSH server with SSHv2 enabled and configured with strong ciphers. ", "SectionThreatMappings": [ { "ReferenceId": "CCC", @@ -5775,20 +3793,20 @@ }, { "Id": "CCC.Core.CN01.AR03", - "Description": "When the service receives unencrypted traffic, \nthen it MUST either block the request or automatically\nredirect it to the secure equivalent.", + "Description": "When the service receives unencrypted traffic, then it MUST either block the request or automatically redirect it to the secure equivalent.", "Attributes": [ { "FamilyName": "Data", - "FamilyDescription": "The Data control family ensures the confidentiality, integrity,\navailability, and sovereignty of data across its lifecycle.\nThese controls govern how data is transmitted, stored,\nreplicated, and protected from unauthorized access, tampering,\nor exposure beyond defined trust perimeters.\n", + "FamilyDescription": "The Data control family ensures the confidentiality, integrity, availability, and sovereignty of data across its lifecycle. These controls govern how data is transmitted, stored, replicated, and protected from unauthorized access, tampering, or exposure beyond defined trust perimeters. ", "Section": "CCC.Core.CN01 Encrypt Data for Transmission", "SubSection": "", - "SubSectionObjective": "Ensure that all communications are encrypted in transit to protect\ndata integrity and confidentiality.", + "SubSectionObjective": "Ensure that all communications are encrypted in transit to protect data integrity and confidentiality.", "Applicability": [ "tlp-green", "tlp-amber", "tlp-red" ], - "Recommendation": "Review firewall, load balancer, and application configurations to\nensure insecure protocols such as HTTP, FTP, and Telnet are not\nexposed. Where possible, implement automatic redirection to secure\nprotocols such as HTTPS, SFTP, SSH, and regularly scan for\nprotocol drift.\n", + "Recommendation": "Review firewall, load balancer, and application configurations to ensure insecure protocols such as HTTP, FTP, and Telnet are not exposed. Where possible, implement automatic redirection to secure protocols such as HTTPS, SFTP, SSH, and regularly scan for protocol drift. ", "SectionThreatMappings": [ { "ReferenceId": "CCC", @@ -5841,21 +3859,21 @@ }, { "Id": "CCC.Core.CN01.AR07", - "Description": "When a port is exposed, the service MUST ensure that the protocol\nand service officially assigned to that port number by the IANA\nService Name and Transport Protocol Port Number Registry, and no\nother, is run on that port.", + "Description": "When a port is exposed, the service MUST ensure that the protocol and service officially assigned to that port number by the IANA Service Name and Transport Protocol Port Number Registry, and no other, is run on that port.", "Attributes": [ { "FamilyName": "Data", - "FamilyDescription": "The Data control family ensures the confidentiality, integrity,\navailability, and sovereignty of data across its lifecycle.\nThese controls govern how data is transmitted, stored,\nreplicated, and protected from unauthorized access, tampering,\nor exposure beyond defined trust perimeters.\n", + "FamilyDescription": "The Data control family ensures the confidentiality, integrity, availability, and sovereignty of data across its lifecycle. These controls govern how data is transmitted, stored, replicated, and protected from unauthorized access, tampering, or exposure beyond defined trust perimeters. ", "Section": "CCC.Core.CN01 Encrypt Data for Transmission", "SubSection": "", - "SubSectionObjective": "Ensure that all communications are encrypted in transit to protect\ndata integrity and confidentiality.", + "SubSectionObjective": "Ensure that all communications are encrypted in transit to protect data integrity and confidentiality.", "Applicability": [ "tlp-clear", "tlp-green", "tlp-amber", "tlp-red" ], - "Recommendation": "Reference the IANA Service Name and Transport Protocol Port Number\nRegistry for more information about correct protocol-to-port\nassignments. Avoid running non-standard services on well-known\nports.\n", + "Recommendation": "Reference the IANA Service Name and Transport Protocol Port Number Registry for more information about correct protocol-to-port assignments. Avoid running non-standard services on well-known ports. ", "SectionThreatMappings": [ { "ReferenceId": "CCC", @@ -5903,19 +3921,19 @@ }, { "Id": "CCC.Core.CN01.AR08", - "Description": "When a service transmits data using TLS, mutual TLS (mTLS) MUST be\nimplemented to require both client and server certificate\nauthentication for all connections.", + "Description": "When a service transmits data using TLS, mutual TLS (mTLS) MUST be implemented to require both client and server certificate authentication for all connections.", "Attributes": [ { "FamilyName": "Data", - "FamilyDescription": "The Data control family ensures the confidentiality, integrity,\navailability, and sovereignty of data across its lifecycle.\nThese controls govern how data is transmitted, stored,\nreplicated, and protected from unauthorized access, tampering,\nor exposure beyond defined trust perimeters.\n", + "FamilyDescription": "The Data control family ensures the confidentiality, integrity, availability, and sovereignty of data across its lifecycle. These controls govern how data is transmitted, stored, replicated, and protected from unauthorized access, tampering, or exposure beyond defined trust perimeters. ", "Section": "CCC.Core.CN01 Encrypt Data for Transmission", "SubSection": "", - "SubSectionObjective": "Ensure that all communications are encrypted in transit to protect\ndata integrity and confidentiality.", + "SubSectionObjective": "Ensure that all communications are encrypted in transit to protect data integrity and confidentiality.", "Applicability": [ "tlp-amber", "tlp-red" ], - "Recommendation": "Configure mTLS for all endpoints that process or transmit\nsensitive data. Ensure both client and server certificates are\nvalidated and managed securely. Regularly review certificate\nauthorities and automate certificate rotation where possible.\n", + "Recommendation": "Configure mTLS for all endpoints that process or transmit sensitive data. Ensure both client and server certificates are validated and managed securely. Regularly review certificate authorities and automate certificate rotation where possible. ", "SectionThreatMappings": [ { "ReferenceId": "CCC", @@ -5962,21 +3980,21 @@ }, { "Id": "CCC.Core.CN13.AR01", - "Description": "When a port is exposed that uses certificate-based encryption,\nthe service MUST only use valid, unexpired certificates issued by\na trusted certificate authority.", + "Description": "When a port is exposed that uses certificate-based encryption, the service MUST only use valid, unexpired certificates issued by a trusted certificate authority.", "Attributes": [ { "FamilyName": "Data", - "FamilyDescription": "The Data control family ensures the confidentiality, integrity,\navailability, and sovereignty of data across its lifecycle.\nThese controls govern how data is transmitted, stored,\nreplicated, and protected from unauthorized access, tampering,\nor exposure beyond defined trust perimeters.\n", + "FamilyDescription": "The Data control family ensures the confidentiality, integrity, availability, and sovereignty of data across its lifecycle. These controls govern how data is transmitted, stored, replicated, and protected from unauthorized access, tampering, or exposure beyond defined trust perimeters. ", "Section": "CCC.Core.CN13 Minimize Lifetime of Encryption and Authentication Certificates", "SubSection": "", - "SubSectionObjective": "Ensure that encryption and authentication certificates have a limited\nlifetime to reduce the risk of compromise and ensure the use of\nup-to-date security practices.", + "SubSectionObjective": "Ensure that encryption and authentication certificates have a limited lifetime to reduce the risk of compromise and ensure the use of up-to-date security practices.", "Applicability": [ "tlp-clear", "tlp-green", "tlp-amber", "tlp-red" ], - "Recommendation": "Track certificate expiration dates and automate certificate\nrenewal where possible. Use certificate management tools to ensure\nonly certificates from trusted authorities are deployed.\n", + "Recommendation": "Track certificate expiration dates and automate certificate renewal where possible. Use certificate management tools to ensure only certificates from trusted authorities are deployed. ", "SectionThreatMappings": [ { "ReferenceId": "CCC", @@ -5992,18 +4010,18 @@ }, { "Id": "CCC.Core.CN13.AR02", - "Description": "When a port is exposed that uses certificate-based encryption,\nthe service MUST rotate active certificates within 180 days of\nissuance.", + "Description": "When a port is exposed that uses certificate-based encryption, the service MUST rotate active certificates within 180 days of issuance.", "Attributes": [ { "FamilyName": "Data", - "FamilyDescription": "The Data control family ensures the confidentiality, integrity,\navailability, and sovereignty of data across its lifecycle.\nThese controls govern how data is transmitted, stored,\nreplicated, and protected from unauthorized access, tampering,\nor exposure beyond defined trust perimeters.\n", + "FamilyDescription": "The Data control family ensures the confidentiality, integrity, availability, and sovereignty of data across its lifecycle. These controls govern how data is transmitted, stored, replicated, and protected from unauthorized access, tampering, or exposure beyond defined trust perimeters. ", "Section": "CCC.Core.CN13 Minimize Lifetime of Encryption and Authentication Certificates", "SubSection": "", - "SubSectionObjective": "Ensure that encryption and authentication certificates have a limited\nlifetime to reduce the risk of compromise and ensure the use of\nup-to-date security practices.", + "SubSectionObjective": "Ensure that encryption and authentication certificates have a limited lifetime to reduce the risk of compromise and ensure the use of up-to-date security practices.", "Applicability": [ "tlp-amber" ], - "Recommendation": "Track certificate expiration dates and automate certificate\nrenewal where possible. Use certificate management tools to ensure\nonly certificates from trusted authorities are deployed.\n", + "Recommendation": "Track certificate expiration dates and automate certificate renewal where possible. Use certificate management tools to ensure only certificates from trusted authorities are deployed. ", "SectionThreatMappings": [ { "ReferenceId": "CCC", @@ -6019,18 +4037,18 @@ }, { "Id": "CCC.Core.CN13.AR03", - "Description": "When a port is exposed that uses certificate-based encryption,\nthe service MUST rotate active certificates within 90 days of\nissuance.", + "Description": "When a port is exposed that uses certificate-based encryption, the service MUST rotate active certificates within 90 days of issuance.", "Attributes": [ { "FamilyName": "Data", - "FamilyDescription": "The Data control family ensures the confidentiality, integrity,\navailability, and sovereignty of data across its lifecycle.\nThese controls govern how data is transmitted, stored,\nreplicated, and protected from unauthorized access, tampering,\nor exposure beyond defined trust perimeters.\n", + "FamilyDescription": "The Data control family ensures the confidentiality, integrity, availability, and sovereignty of data across its lifecycle. These controls govern how data is transmitted, stored, replicated, and protected from unauthorized access, tampering, or exposure beyond defined trust perimeters. ", "Section": "CCC.Core.CN13 Minimize Lifetime of Encryption and Authentication Certificates", "SubSection": "", - "SubSectionObjective": "Ensure that encryption and authentication certificates have a limited\nlifetime to reduce the risk of compromise and ensure the use of\nup-to-date security practices.", + "SubSectionObjective": "Ensure that encryption and authentication certificates have a limited lifetime to reduce the risk of compromise and ensure the use of up-to-date security practices.", "Applicability": [ "tlp-red" ], - "Recommendation": "Track certificate expiration dates and automate certificate\nrenewal where possible. Use certificate management tools to ensure\nonly certificates from trusted authorities are deployed.\n", + "Recommendation": "Track certificate expiration dates and automate certificate renewal where possible. Use certificate management tools to ensure only certificates from trusted authorities are deployed. ", "SectionThreatMappings": [ { "ReferenceId": "CCC", @@ -6049,21 +4067,21 @@ }, { "Id": "CCC.Core.CN06.AR01", - "Description": "When the service is running, its region and availability zone MUST\nbe included in a list of explicitly trusted or approved locations\nwithin the trust perimeter.", + "Description": "When the service is running, its region and availability zone MUST be included in a list of explicitly trusted or approved locations within the trust perimeter.", "Attributes": [ { "FamilyName": "Data", - "FamilyDescription": "The Data control family ensures the confidentiality, integrity,\navailability, and sovereignty of data across its lifecycle.\nThese controls govern how data is transmitted, stored,\nreplicated, and protected from unauthorized access, tampering,\nor exposure beyond defined trust perimeters.\n", + "FamilyDescription": "The Data control family ensures the confidentiality, integrity, availability, and sovereignty of data across its lifecycle. These controls govern how data is transmitted, stored, replicated, and protected from unauthorized access, tampering, or exposure beyond defined trust perimeters. ", "Section": "CCC.Core.CN06 Restrict Deployments to Trust Perimeter", "SubSection": "", - "SubSectionObjective": "Ensure that the service and its child resources are only deployed on\ninfrastructure in locations that are explicitly included within a\ndefined trust perimeter.", + "SubSectionObjective": "Ensure that the service and its child resources are only deployed on infrastructure in locations that are explicitly included within a defined trust perimeter.", "Applicability": [ "tlp-clear", "tlp-green", "tlp-amber", "tlp-red" ], - "Recommendation": "Maintain an up-to-date list of trusted and approved regions based\non organizational policies. Validate the service's deployment\nlocation is included in this list.\n", + "Recommendation": "Maintain an up-to-date list of trusted and approved regions based on organizational policies. Validate the service's deployment location is included in this list. ", "SectionThreatMappings": [ { "ReferenceId": "CCC", @@ -6104,21 +4122,21 @@ }, { "Id": "CCC.Core.CN06.AR02", - "Description": "When a child resource is deployed, its region and availability\nzone MUST be included in a list of explicitly trusted or approved\nlocations within the trust perimeter.", + "Description": "When a child resource is deployed, its region and availability zone MUST be included in a list of explicitly trusted or approved locations within the trust perimeter.", "Attributes": [ { "FamilyName": "Data", - "FamilyDescription": "The Data control family ensures the confidentiality, integrity,\navailability, and sovereignty of data across its lifecycle.\nThese controls govern how data is transmitted, stored,\nreplicated, and protected from unauthorized access, tampering,\nor exposure beyond defined trust perimeters.\n", + "FamilyDescription": "The Data control family ensures the confidentiality, integrity, availability, and sovereignty of data across its lifecycle. These controls govern how data is transmitted, stored, replicated, and protected from unauthorized access, tampering, or exposure beyond defined trust perimeters. ", "Section": "CCC.Core.CN06 Restrict Deployments to Trust Perimeter", "SubSection": "", - "SubSectionObjective": "Ensure that the service and its child resources are only deployed on\ninfrastructure in locations that are explicitly included within a\ndefined trust perimeter.", + "SubSectionObjective": "Ensure that the service and its child resources are only deployed on infrastructure in locations that are explicitly included within a defined trust perimeter.", "Applicability": [ "tlp-clear", "tlp-green", "tlp-amber", "tlp-red" ], - "Recommendation": "Maintain an up-to-date list of trusted and approved regions based\non organizational policies. Validate that child resources can only\nbe deployed to locations included in this list.\n", + "Recommendation": "Maintain an up-to-date list of trusted and approved regions based on organizational policies. Validate that child resources can only be deployed to locations included in this list. ", "SectionThreatMappings": [ { "ReferenceId": "CCC", @@ -6159,20 +4177,20 @@ }, { "Id": "CCC.Core.CN08.AR01", - "Description": "When data is created or modified, the data MUST have a complete\nand recoverable duplicate that is stored in a physically separate\ndata center.", + "Description": "When data is created or modified, the data MUST have a complete and recoverable duplicate that is stored in a physically separate data center.", "Attributes": [ { "FamilyName": "Data", - "FamilyDescription": "The Data control family ensures the confidentiality, integrity,\navailability, and sovereignty of data across its lifecycle.\nThese controls govern how data is transmitted, stored,\nreplicated, and protected from unauthorized access, tampering,\nor exposure beyond defined trust perimeters.\n", + "FamilyDescription": "The Data control family ensures the confidentiality, integrity, availability, and sovereignty of data across its lifecycle. These controls govern how data is transmitted, stored, replicated, and protected from unauthorized access, tampering, or exposure beyond defined trust perimeters. ", "Section": "CCC.Core.CN08 Replicate Data to Multiple Locations", "SubSection": "", - "SubSectionObjective": "Ensure that data is replicated across multiple physical locations to\nprotect against data loss due to hardware failures, natural disasters,\nor other catastrophic events.", + "SubSectionObjective": "Ensure that data is replicated across multiple physical locations to protect against data loss due to hardware failures, natural disasters, or other catastrophic events.", "Applicability": [ "tlp-green", "tlp-amber", "tlp-red" ], - "Recommendation": "Implement automated data replication processes to ensure that\ndata is consistently duplicated in another region or availability\nzone. Regularly test data recovery from the replicated location to\nensure integrity and availability.\n", + "Recommendation": "Implement automated data replication processes to ensure that data is consistently duplicated in another region or availability zone. Regularly test data recovery from the replicated location to ensure integrity and availability. ", "SectionThreatMappings": [ { "ReferenceId": "CCC", @@ -6213,14 +4231,14 @@ }, { "Id": "CCC.Core.CN08.AR02", - "Description": "When data is replicated into a second location, the service MUST\nbe able to accurately represent the replication locations,\nreplication status, and data synchronization status.", + "Description": "When data is replicated into a second location, the service MUST be able to accurately represent the replication locations, replication status, and data synchronization status.", "Attributes": [ { "FamilyName": "Data", - "FamilyDescription": "The Data control family ensures the confidentiality, integrity,\navailability, and sovereignty of data across its lifecycle.\nThese controls govern how data is transmitted, stored,\nreplicated, and protected from unauthorized access, tampering,\nor exposure beyond defined trust perimeters.\n", + "FamilyDescription": "The Data control family ensures the confidentiality, integrity, availability, and sovereignty of data across its lifecycle. These controls govern how data is transmitted, stored, replicated, and protected from unauthorized access, tampering, or exposure beyond defined trust perimeters. ", "Section": "CCC.Core.CN08 Replicate Data to Multiple Locations", "SubSection": "", - "SubSectionObjective": "Ensure that data is replicated across multiple physical locations to\nprotect against data loss due to hardware failures, natural disasters,\nor other catastrophic events.", + "SubSectionObjective": "Ensure that data is replicated across multiple physical locations to protect against data loss due to hardware failures, natural disasters, or other catastrophic events.", "Applicability": [ "tlp-green", "tlp-amber", @@ -6264,14 +4282,14 @@ }, { "Id": "CCC.Core.CN09.AR01", - "Description": "When the service is operational, its logs and any child resource\nlogs MUST NOT be accessible from the resource they record access\nto.", + "Description": "When the service is operational, its logs and any child resource logs MUST NOT be accessible from the resource they record access to.", "Attributes": [ { "FamilyName": "Data", - "FamilyDescription": "The Data control family ensures the confidentiality, integrity,\navailability, and sovereignty of data across its lifecycle.\nThese controls govern how data is transmitted, stored,\nreplicated, and protected from unauthorized access, tampering,\nor exposure beyond defined trust perimeters.\n", + "FamilyDescription": "The Data control family ensures the confidentiality, integrity, availability, and sovereignty of data across its lifecycle. These controls govern how data is transmitted, stored, replicated, and protected from unauthorized access, tampering, or exposure beyond defined trust perimeters. ", "Section": "CCC.Core.CN09 Ensure Integrity of Access Logs", "SubSection": "", - "SubSectionObjective": "Ensure that access logs are always recorded to an external location\nthat cannot be manipulated from the context of the service(s) it\ncontains logs for.", + "SubSectionObjective": "Ensure that access logs are always recorded to an external location that cannot be manipulated from the context of the service(s) it contains logs for.", "Applicability": [ "tlp-clear", "tlp-green", @@ -6321,21 +4339,21 @@ }, { "Id": "CCC.Core.CN09.AR02", - "Description": "When the service is operational, disabling the logs for the service\nor its child resources MUST NOT be possible without also disabling\nthe corresponding resource.", + "Description": "When the service is operational, disabling the logs for the service or its child resources MUST NOT be possible without also disabling the corresponding resource.", "Attributes": [ { "FamilyName": "Data", - "FamilyDescription": "The Data control family ensures the confidentiality, integrity,\navailability, and sovereignty of data across its lifecycle.\nThese controls govern how data is transmitted, stored,\nreplicated, and protected from unauthorized access, tampering,\nor exposure beyond defined trust perimeters.\n", + "FamilyDescription": "The Data control family ensures the confidentiality, integrity, availability, and sovereignty of data across its lifecycle. These controls govern how data is transmitted, stored, replicated, and protected from unauthorized access, tampering, or exposure beyond defined trust perimeters. ", "Section": "CCC.Core.CN09 Ensure Integrity of Access Logs", "SubSection": "", - "SubSectionObjective": "Ensure that access logs are always recorded to an external location\nthat cannot be manipulated from the context of the service(s) it\ncontains logs for.", + "SubSectionObjective": "Ensure that access logs are always recorded to an external location that cannot be manipulated from the context of the service(s) it contains logs for.", "Applicability": [ "tlp-clear", "tlp-green", "tlp-amber", "tlp-red" ], - "Recommendation": "No normal business operations should disable\nlogs, as this could indicate an attempt to cover up unauthorized\naccess. Ensure that logging mechanisms are tightly integrated with\nservice operations, so that logging cannot be disabled without\nstopping the service itself.\n", + "Recommendation": "No normal business operations should disable logs, as this could indicate an attempt to cover up unauthorized access. Ensure that logging mechanisms are tightly integrated with service operations, so that logging cannot be disabled without stopping the service itself. ", "SectionThreatMappings": [ { "ReferenceId": "CCC", @@ -6381,19 +4399,19 @@ }, { "Id": "CCC.Core.CN09.AR03", - "Description": "When the service is operational, any attempt to redirect logs for\nthe service or its child resources MUST NOT be possible without\nhalting operation of the corresponding resource and publishing\ncorresponding events to monitored channels.", + "Description": "When the service is operational, any attempt to redirect logs for the service or its child resources MUST NOT be possible without halting operation of the corresponding resource and publishing corresponding events to monitored channels.", "Attributes": [ { "FamilyName": "Data", - "FamilyDescription": "The Data control family ensures the confidentiality, integrity,\navailability, and sovereignty of data across its lifecycle.\nThese controls govern how data is transmitted, stored,\nreplicated, and protected from unauthorized access, tampering,\nor exposure beyond defined trust perimeters.\n", + "FamilyDescription": "The Data control family ensures the confidentiality, integrity, availability, and sovereignty of data across its lifecycle. These controls govern how data is transmitted, stored, replicated, and protected from unauthorized access, tampering, or exposure beyond defined trust perimeters. ", "Section": "CCC.Core.CN09 Ensure Integrity of Access Logs", "SubSection": "", - "SubSectionObjective": "Ensure that access logs are always recorded to an external location\nthat cannot be manipulated from the context of the service(s) it\ncontains logs for.", + "SubSectionObjective": "Ensure that access logs are always recorded to an external location that cannot be manipulated from the context of the service(s) it contains logs for.", "Applicability": [ "tlp-amber", "tlp-red" ], - "Recommendation": "No normal business operations should result in the redirection of\nlogs, as this could indicate an attempt to cover up unauthorized\naccess. Ensure that logging configurations are immutable during\nservice operation so that any changes require stopping the service\nand publishing corresponding events to monitored channels.\n", + "Recommendation": "No normal business operations should result in the redirection of logs, as this could indicate an attempt to cover up unauthorized access. Ensure that logging configurations are immutable during service operation so that any changes require stopping the service and publishing corresponding events to monitored channels. ", "SectionThreatMappings": [ { "ReferenceId": "CCC", @@ -6435,14 +4453,14 @@ }, { "Id": "CCC.Core.CN10.AR01", - "Description": "When data is replicated, the service MUST ensure that replication\nonly occurs to destinations that are explicitly included within\nthe defined trust perimeter.", + "Description": "When data is replicated, the service MUST ensure that replication only occurs to destinations that are explicitly included within the defined trust perimeter.", "Attributes": [ { "FamilyName": "Data", - "FamilyDescription": "The Data control family ensures the confidentiality, integrity,\navailability, and sovereignty of data across its lifecycle.\nThese controls govern how data is transmitted, stored,\nreplicated, and protected from unauthorized access, tampering,\nor exposure beyond defined trust perimeters.\n", + "FamilyDescription": "The Data control family ensures the confidentiality, integrity, availability, and sovereignty of data across its lifecycle. These controls govern how data is transmitted, stored, replicated, and protected from unauthorized access, tampering, or exposure beyond defined trust perimeters. ", "Section": "CCC.Core.CN10 Restrict Data Replication to Trust Perimeter", "SubSection": "", - "SubSectionObjective": "Ensure that data is only replicated on infrastructure in locations\nthat are explicitly included within a defined trust perimeter.", + "SubSectionObjective": "Ensure that data is only replicated on infrastructure in locations that are explicitly included within a defined trust perimeter.", "Applicability": [ "tlp-green", "tlp-amber", @@ -6484,14 +4502,14 @@ }, { "Id": "CCC.Core.CN02.AR01", - "Description": "When data is stored, it MUST be encrypted using the latest\nindustry-standard encryption methods.", + "Description": "When data is stored, it MUST be encrypted using the latest industry-standard encryption methods.", "Attributes": [ { "FamilyName": "Data", - "FamilyDescription": "The Data control family ensures the confidentiality, integrity,\navailability, and sovereignty of data across its lifecycle.\nThese controls govern how data is transmitted, stored,\nreplicated, and protected from unauthorized access, tampering,\nor exposure beyond defined trust perimeters.\n", + "FamilyDescription": "The Data control family ensures the confidentiality, integrity, availability, and sovereignty of data across its lifecycle. These controls govern how data is transmitted, stored, replicated, and protected from unauthorized access, tampering, or exposure beyond defined trust perimeters. ", "Section": "CCC.Core.CN02 Encrypt Data for Storage", "SubSection": "", - "SubSectionObjective": "Ensure that all data stored is encrypted at rest using strong\nencryption algorithms.", + "SubSectionObjective": "Ensure that all data stored is encrypted at rest using strong encryption algorithms.", "Applicability": [ "tlp-green", "tlp-amber", @@ -6543,14 +4561,14 @@ }, { "Id": "CCC.Core.CN11.AR01", - "Description": "When encryption keys are used, the service MUST verify that\nall encryption keys use the latest industry-standard cryptographic\nalgorithms.", + "Description": "When encryption keys are used, the service MUST verify that all encryption keys use the latest industry-standard cryptographic algorithms.", "Attributes": [ { "FamilyName": "Data", - "FamilyDescription": "The Data control family ensures the confidentiality, integrity,\navailability, and sovereignty of data across its lifecycle.\nThese controls govern how data is transmitted, stored,\nreplicated, and protected from unauthorized access, tampering,\nor exposure beyond defined trust perimeters.\n", + "FamilyDescription": "The Data control family ensures the confidentiality, integrity, availability, and sovereignty of data across its lifecycle. These controls govern how data is transmitted, stored, replicated, and protected from unauthorized access, tampering, or exposure beyond defined trust perimeters. ", "Section": "CCC.Core.CN11 Protect Encryption Keys", "SubSection": "", - "SubSectionObjective": "Ensure that encryption keys are managed securely by enforcing\nthe use of approved algorithms, regular key rotation, and\ncustomer-managed encryption keys (CMEKs).", + "SubSectionObjective": "Ensure that encryption keys are managed securely by enforcing the use of approved algorithms, regular key rotation, and customer-managed encryption keys (CMEKs).", "Applicability": [ "tlp-amber", "tlp-red" @@ -6605,14 +4623,14 @@ }, { "Id": "CCC.Core.CN11.AR02", - "Description": "When encryption keys are used, the service MUST rotate active keys\nwithin 180 days of issuance.", + "Description": "When encryption keys are used, the service MUST rotate active keys within 180 days of issuance.", "Attributes": [ { "FamilyName": "Data", - "FamilyDescription": "The Data control family ensures the confidentiality, integrity,\navailability, and sovereignty of data across its lifecycle.\nThese controls govern how data is transmitted, stored,\nreplicated, and protected from unauthorized access, tampering,\nor exposure beyond defined trust perimeters.\n", + "FamilyDescription": "The Data control family ensures the confidentiality, integrity, availability, and sovereignty of data across its lifecycle. These controls govern how data is transmitted, stored, replicated, and protected from unauthorized access, tampering, or exposure beyond defined trust perimeters. ", "Section": "CCC.Core.CN11 Protect Encryption Keys", "SubSection": "", - "SubSectionObjective": "Ensure that encryption keys are managed securely by enforcing\nthe use of approved algorithms, regular key rotation, and\ncustomer-managed encryption keys (CMEKs).", + "SubSectionObjective": "Ensure that encryption keys are managed securely by enforcing the use of approved algorithms, regular key rotation, and customer-managed encryption keys (CMEKs).", "Applicability": [ "tlp-amber" ], @@ -6666,14 +4684,14 @@ }, { "Id": "CCC.Core.CN11.AR03", - "Description": "When encrypting data, the service MUST verify that\ncustomer-managed encryption keys (CMEKs) are used.", + "Description": "When encrypting data, the service MUST verify that customer-managed encryption keys (CMEKs) are used.", "Attributes": [ { "FamilyName": "Data", - "FamilyDescription": "The Data control family ensures the confidentiality, integrity,\navailability, and sovereignty of data across its lifecycle.\nThese controls govern how data is transmitted, stored,\nreplicated, and protected from unauthorized access, tampering,\nor exposure beyond defined trust perimeters.\n", + "FamilyDescription": "The Data control family ensures the confidentiality, integrity, availability, and sovereignty of data across its lifecycle. These controls govern how data is transmitted, stored, replicated, and protected from unauthorized access, tampering, or exposure beyond defined trust perimeters. ", "Section": "", "SubSection": "CCC.Core.CN11 Protect Encryption Keys", - "SubSectionObjective": "Ensure that encryption keys are managed securely by enforcing\nthe use of approved algorithms, regular key rotation, and\ncustomer-managed encryption keys (CMEKs).", + "SubSectionObjective": "Ensure that encryption keys are managed securely by enforcing the use of approved algorithms, regular key rotation, and customer-managed encryption keys (CMEKs).", "Applicability": [ "tlp-amber", "tlp-red" @@ -6728,14 +4746,14 @@ }, { "Id": "CCC.Core.CN11.AR04", - "Description": "When encryption keys are accessed, the service MUST verify that\naccess to encryption keys is restricted to authorized personnel\nand services, following the principle of least privilege.", + "Description": "When encryption keys are accessed, the service MUST verify that access to encryption keys is restricted to authorized personnel and services, following the principle of least privilege.", "Attributes": [ { "FamilyName": "Data", - "FamilyDescription": "The Data control family ensures the confidentiality, integrity,\navailability, and sovereignty of data across its lifecycle.\nThese controls govern how data is transmitted, stored,\nreplicated, and protected from unauthorized access, tampering,\nor exposure beyond defined trust perimeters.\n", + "FamilyDescription": "The Data control family ensures the confidentiality, integrity, availability, and sovereignty of data across its lifecycle. These controls govern how data is transmitted, stored, replicated, and protected from unauthorized access, tampering, or exposure beyond defined trust perimeters. ", "Section": "CCC.Core.CN11 Protect Encryption Keys", "SubSection": "", - "SubSectionObjective": "Ensure that encryption keys are managed securely by enforcing\nthe use of approved algorithms, regular key rotation, and\ncustomer-managed encryption keys (CMEKs).", + "SubSectionObjective": "Ensure that encryption keys are managed securely by enforcing the use of approved algorithms, regular key rotation, and customer-managed encryption keys (CMEKs).", "Applicability": [ "tlp-clear", "tlp-green", @@ -6792,14 +4810,14 @@ }, { "Id": "CCC.Core.CN11.AR05", - "Description": "When encryption keys are used, the service MUST rotate active keys\nwithin 365 days of issuance.", + "Description": "When encryption keys are used, the service MUST rotate active keys within 365 days of issuance.", "Attributes": [ { "FamilyName": "Data", - "FamilyDescription": "The Data control family ensures the confidentiality, integrity,\navailability, and sovereignty of data across its lifecycle.\nThese controls govern how data is transmitted, stored,\nreplicated, and protected from unauthorized access, tampering,\nor exposure beyond defined trust perimeters.\n", + "FamilyDescription": "The Data control family ensures the confidentiality, integrity, availability, and sovereignty of data across its lifecycle. These controls govern how data is transmitted, stored, replicated, and protected from unauthorized access, tampering, or exposure beyond defined trust perimeters. ", "Section": "CCC.Core.CN11 Protect Encryption Keys", "SubSection": "", - "SubSectionObjective": "Ensure that encryption keys are managed securely by enforcing\nthe use of approved algorithms, regular key rotation, and\ncustomer-managed encryption keys (CMEKs).", + "SubSectionObjective": "Ensure that encryption keys are managed securely by enforcing the use of approved algorithms, regular key rotation, and customer-managed encryption keys (CMEKs).", "Applicability": [ "tlp-clear", "tlp-green" @@ -6854,14 +4872,14 @@ }, { "Id": "CCC.Core.CN11.AR06", - "Description": "When encryption keys are used, the service MUST rotate active keys\nwithin 90 days of issuance.", + "Description": "When encryption keys are used, the service MUST rotate active keys within 90 days of issuance.", "Attributes": [ { "FamilyName": "Data", - "FamilyDescription": "The Data control family ensures the confidentiality, integrity,\navailability, and sovereignty of data across its lifecycle.\nThese controls govern how data is transmitted, stored,\nreplicated, and protected from unauthorized access, tampering,\nor exposure beyond defined trust perimeters.\n", + "FamilyDescription": "The Data control family ensures the confidentiality, integrity, availability, and sovereignty of data across its lifecycle. These controls govern how data is transmitted, stored, replicated, and protected from unauthorized access, tampering, or exposure beyond defined trust perimeters. ", "Section": "CCC.Core.CN11 Protect Encryption Keys", "SubSection": "", - "SubSectionObjective": "Ensure that encryption keys are managed securely by enforcing\nthe use of approved algorithms, regular key rotation, and\ncustomer-managed encryption keys (CMEKs).", + "SubSectionObjective": "Ensure that encryption keys are managed securely by enforcing the use of approved algorithms, regular key rotation, and customer-managed encryption keys (CMEKs).", "Applicability": [ "tlp-red" ], @@ -6915,21 +4933,21 @@ }, { "Id": "CCC.Core.CN14.AR01", - "Description": "When backups are created for disaster recovery purposes, the\nstorage mechanism MUST NOT allow modification or deletion\nwithin 30 days of creation.", + "Description": "When backups are created for disaster recovery purposes, the storage mechanism MUST NOT allow modification or deletion within 30 days of creation.", "Attributes": [ { "FamilyName": "Data", - "FamilyDescription": "The Data control family ensures the confidentiality, integrity,\navailability, and sovereignty of data across its lifecycle.\nThese controls govern how data is transmitted, stored,\nreplicated, and protected from unauthorized access, tampering,\nor exposure beyond defined trust perimeters.\n", + "FamilyDescription": "The Data control family ensures the confidentiality, integrity, availability, and sovereignty of data across its lifecycle. These controls govern how data is transmitted, stored, replicated, and protected from unauthorized access, tampering, or exposure beyond defined trust perimeters. ", "Section": "CCC.Core.CN14 Maintain Recent Backups", "SubSection": "", - "SubSectionObjective": "Ensure that all backups used for disaster recovery are recent and\nsubject to a retention policy that limits deletion.", + "SubSectionObjective": "Ensure that all backups used for disaster recovery are recent and subject to a retention policy that limits deletion.", "Applicability": [ "tlp-clear", "tlp-green", "tlp-amber", "tlp-red" ], - "Recommendation": "Use immutable storage solutions where possible. Implement backup\nretention policies that enforce a minimum retention period of 30\ndays.\n", + "Recommendation": "Use immutable storage solutions where possible. Implement backup retention policies that enforce a minimum retention period of 30 days. ", "SectionThreatMappings": [ { "ReferenceId": "CCC", @@ -6948,20 +4966,20 @@ }, { "Id": "CCC.Core.CN14.AR02", - "Description": "When backups are created for disaster recovery purposes, the\nmost recent backup MUST have a creation date within the past\n30 days.", + "Description": "When backups are created for disaster recovery purposes, the most recent backup MUST have a creation date within the past 30 days.", "Attributes": [ { "FamilyName": "Data", - "FamilyDescription": "The Data control family ensures the confidentiality, integrity,\navailability, and sovereignty of data across its lifecycle.\nThese controls govern how data is transmitted, stored,\nreplicated, and protected from unauthorized access, tampering,\nor exposure beyond defined trust perimeters.\n", + "FamilyDescription": "The Data control family ensures the confidentiality, integrity, availability, and sovereignty of data across its lifecycle. These controls govern how data is transmitted, stored, replicated, and protected from unauthorized access, tampering, or exposure beyond defined trust perimeters. ", "Section": "CCC.Core.CN14 Maintain Recent Backups", "SubSection": "", - "SubSectionObjective": "Ensure that all backups used for disaster recovery are recent and\nsubject to a retention policy that limits deletion.", + "SubSectionObjective": "Ensure that all backups used for disaster recovery are recent and subject to a retention policy that limits deletion.", "Applicability": [ "tlp-clear", "tlp-green", "tlp-amber" ], - "Recommendation": "Implement automated backup processes to ensure that backups are\ncreated regularly. Monitor backup schedules and verify that the\nmost recent backup creation date is within the last 30 days.\n", + "Recommendation": "Implement automated backup processes to ensure that backups are created regularly. Monitor backup schedules and verify that the most recent backup creation date is within the last 30 days. ", "SectionThreatMappings": [ { "ReferenceId": "CCC", @@ -6979,18 +4997,18 @@ }, { "Id": "CCC.Core.CN14.AR02", - "Description": "When backups are created for disaster recovery purposes, the\nmost recent backup MUST have a creation date within the past\n14 days.", + "Description": "When backups are created for disaster recovery purposes, the most recent backup MUST have a creation date within the past 14 days.", "Attributes": [ { "FamilyName": "Data", - "FamilyDescription": "The Data control family ensures the confidentiality, integrity,\navailability, and sovereignty of data across its lifecycle.\nThese controls govern how data is transmitted, stored,\nreplicated, and protected from unauthorized access, tampering,\nor exposure beyond defined trust perimeters.\n", + "FamilyDescription": "The Data control family ensures the confidentiality, integrity, availability, and sovereignty of data across its lifecycle. These controls govern how data is transmitted, stored, replicated, and protected from unauthorized access, tampering, or exposure beyond defined trust perimeters. ", "Section": "CCC.Core.CN14 Maintain Recent Backups", "SubSection": "", - "SubSectionObjective": "Ensure that all backups used for disaster recovery are recent and\nsubject to a retention policy that limits deletion.", + "SubSectionObjective": "Ensure that all backups used for disaster recovery are recent and subject to a retention policy that limits deletion.", "Applicability": [ "tlp-red" ], - "Recommendation": "Implement automated backup processes to ensure that backups are\ncreated regularly. Monitor backup schedules and verify that the\nmost recent backup creation date is within the last 14 days.\n", + "Recommendation": "Implement automated backup processes to ensure that backups are created regularly. Monitor backup schedules and verify that the most recent backup creation date is within the last 14 days. ", "SectionThreatMappings": [ { "ReferenceId": "CCC", @@ -7009,14 +5027,14 @@ }, { "Id": "CCC.Core.CN03.AR01", - "Description": "When an entity attempts to modify the service through a user\ninterface, the authentication process MUST require multiple\nidentifying factors for authentication.", + "Description": "When an entity attempts to modify the service through a user interface, the authentication process MUST require multiple identifying factors for authentication.", "Attributes": [ { "FamilyName": "Identity and Access Management", - "FamilyDescription": "The Identity and Access Management control family ensures\nthat only trusted and authenticated entities can access\nresources. These controls establish strong authentication,\nenforce multi-factor verification, and restrict access to\napproved sources to prevent unauthorized use or data exfiltration.\n", + "FamilyDescription": "The Identity and Access Management control family ensures that only trusted and authenticated entities can access resources. These controls establish strong authentication, enforce multi-factor verification, and restrict access to approved sources to prevent unauthorized use or data exfiltration. ", "Section": "CCC.Core.CN03 Implement Multi-factor Authentication (MFA) for Access", "SubSection": "", - "SubSectionObjective": "Ensure that all sensitive activities require two or more identity\nfactors during authentication to prevent unauthorized access.", + "SubSectionObjective": "Ensure that all sensitive activities require two or more identity factors during authentication to prevent unauthorized access.", "Applicability": [ "tlp-clear", "tlp-green", @@ -7071,14 +5089,14 @@ }, { "Id": "CCC.Core.CN03.AR02", - "Description": "When an entity attempts to modify the service through an API\nendpoint, the authentication process MUST require a credential\nsuch as an API key or token AND originate from within the trust\nperimeter.", + "Description": "When an entity attempts to modify the service through an API endpoint, the authentication process MUST require a credential such as an API key or token AND originate from within the trust perimeter.", "Attributes": [ { "FamilyName": "Identity and Access Management", - "FamilyDescription": "The Identity and Access Management control family ensures\nthat only trusted and authenticated entities can access\nresources. These controls establish strong authentication,\nenforce multi-factor verification, and restrict access to\napproved sources to prevent unauthorized use or data exfiltration.\n", + "FamilyDescription": "The Identity and Access Management control family ensures that only trusted and authenticated entities can access resources. These controls establish strong authentication, enforce multi-factor verification, and restrict access to approved sources to prevent unauthorized use or data exfiltration. ", "Section": "CCC.Core.CN03 Implement Multi-factor Authentication (MFA) for Access", "SubSection": "", - "SubSectionObjective": "Ensure that all sensitive activities require two or more identity\nfactors during authentication to prevent unauthorized access.", + "SubSectionObjective": "Ensure that all sensitive activities require two or more identity factors during authentication to prevent unauthorized access.", "Applicability": [ "tlp-clear", "tlp-green", @@ -7142,14 +5160,14 @@ }, { "Id": "CCC.Core.CN03.AR03", - "Description": "When an entity attempts to view information on the service through\na user interface, the authentication process MUST require multiple\nidentifying factors from the user.", + "Description": "When an entity attempts to view information on the service through a user interface, the authentication process MUST require multiple identifying factors from the user.", "Attributes": [ { "FamilyName": "Identity and Access Management", - "FamilyDescription": "The Identity and Access Management control family ensures\nthat only trusted and authenticated entities can access\nresources. These controls establish strong authentication,\nenforce multi-factor verification, and restrict access to\napproved sources to prevent unauthorized use or data exfiltration.\n", + "FamilyDescription": "The Identity and Access Management control family ensures that only trusted and authenticated entities can access resources. These controls establish strong authentication, enforce multi-factor verification, and restrict access to approved sources to prevent unauthorized use or data exfiltration. ", "Section": "CCC.Core.CN03 Implement Multi-factor Authentication (MFA) for Access", "SubSection": "", - "SubSectionObjective": "Ensure that all sensitive activities require two or more identity\nfactors during authentication to prevent unauthorized access.", + "SubSectionObjective": "Ensure that all sensitive activities require two or more identity factors during authentication to prevent unauthorized access.", "Applicability": [ "tlp-amber", "tlp-red" @@ -7202,14 +5220,14 @@ }, { "Id": "CCC.Core.CN03.AR04", - "Description": "When an entity attempts to view information on the service through\nan API endpoint, the authentication process MUST require a\ncredential such as an API key or token AND originate from within\nthe trust perimeter.", + "Description": "When an entity attempts to view information on the service through an API endpoint, the authentication process MUST require a credential such as an API key or token AND originate from within the trust perimeter.", "Attributes": [ { "FamilyName": "Identity and Access Management", - "FamilyDescription": "The Identity and Access Management control family ensures\nthat only trusted and authenticated entities can access\nresources. These controls establish strong authentication,\nenforce multi-factor verification, and restrict access to\napproved sources to prevent unauthorized use or data exfiltration.\n", + "FamilyDescription": "The Identity and Access Management control family ensures that only trusted and authenticated entities can access resources. These controls establish strong authentication, enforce multi-factor verification, and restrict access to approved sources to prevent unauthorized use or data exfiltration. ", "Section": "CCC.Core.CN03 Implement Multi-factor Authentication (MFA) for Access", "SubSection": "", - "SubSectionObjective": "Ensure that all sensitive activities require two or more identity\nfactors during authentication to prevent unauthorized access.", + "SubSectionObjective": "Ensure that all sensitive activities require two or more identity factors during authentication to prevent unauthorized access.", "Applicability": [ "tlp-amber", "tlp-red" @@ -7272,14 +5290,14 @@ }, { "Id": "CCC.Core.CN05.AR01", - "Description": "When an attempt is made to modify data on the service or a child\nresource, the service MUST block requests from unauthorized\nentities.", + "Description": "When an attempt is made to modify data on the service or a child resource, the service MUST block requests from unauthorized entities.", "Attributes": [ { "FamilyName": "Identity and Access Management", - "FamilyDescription": "The Identity and Access Management control family ensures\nthat only trusted and authenticated entities can access\nresources. These controls establish strong authentication,\nenforce multi-factor verification, and restrict access to\napproved sources to prevent unauthorized use or data exfiltration.\n", + "FamilyDescription": "The Identity and Access Management control family ensures that only trusted and authenticated entities can access resources. These controls establish strong authentication, enforce multi-factor verification, and restrict access to approved sources to prevent unauthorized use or data exfiltration. ", "Section": "CCC.Core.CN05 Prevent Access from Untrusted Entities", "SubSection": "", - "SubSectionObjective": "Ensure that secure access controls enforce the principle of least\nprivilege to restrict access to authorized entities from explicitly\ntrusted sources only.", + "SubSectionObjective": "Ensure that secure access controls enforce the principle of least privilege to restrict access to authorized entities from explicitly trusted sources only.", "Applicability": [ "tlp-clear", "tlp-green", @@ -7351,14 +5369,14 @@ }, { "Id": "CCC.Core.CN05.AR02", - "Description": "When administrative access or configuration change is attempted on\nthe service or a child resource, the service MUST refuse requests\nfrom unauthorized entities.", + "Description": "When administrative access or configuration change is attempted on the service or a child resource, the service MUST refuse requests from unauthorized entities.", "Attributes": [ { "FamilyName": "Identity and Access Management", - "FamilyDescription": "The Identity and Access Management control family ensures\nthat only trusted and authenticated entities can access\nresources. These controls establish strong authentication,\nenforce multi-factor verification, and restrict access to\napproved sources to prevent unauthorized use or data exfiltration.\n", + "FamilyDescription": "The Identity and Access Management control family ensures that only trusted and authenticated entities can access resources. These controls establish strong authentication, enforce multi-factor verification, and restrict access to approved sources to prevent unauthorized use or data exfiltration. ", "Section": "CCC.Core.CN05 Prevent Access from Untrusted Entities", "SubSection": "", - "SubSectionObjective": "Ensure that secure access controls enforce the principle of least\nprivilege to restrict access to authorized entities from explicitly\ntrusted sources only.", + "SubSectionObjective": "Ensure that secure access controls enforce the principle of least privilege to restrict access to authorized entities from explicitly trusted sources only.", "Applicability": [ "tlp-clear", "tlp-green", @@ -7433,14 +5451,14 @@ }, { "Id": "CCC.Core.CN05.AR03", - "Description": "When administrative access or configuration change is attempted on\nthe service or a child resource in a multi-tenant environment, the\nservice MUST refuse requests across tenant boundaries unless the\norigin is explicitly included in a pre-approved allowlist.", + "Description": "When administrative access or configuration change is attempted on the service or a child resource in a multi-tenant environment, the service MUST refuse requests across tenant boundaries unless the origin is explicitly included in a pre-approved allowlist.", "Attributes": [ { "FamilyName": "Identity and Access Management", - "FamilyDescription": "The Identity and Access Management control family ensures\nthat only trusted and authenticated entities can access\nresources. These controls establish strong authentication,\nenforce multi-factor verification, and restrict access to\napproved sources to prevent unauthorized use or data exfiltration.\n", + "FamilyDescription": "The Identity and Access Management control family ensures that only trusted and authenticated entities can access resources. These controls establish strong authentication, enforce multi-factor verification, and restrict access to approved sources to prevent unauthorized use or data exfiltration. ", "Section": "CCC.Core.CN05 Prevent Access from Untrusted Entities", "SubSection": "", - "SubSectionObjective": "Ensure that secure access controls enforce the principle of least\nprivilege to restrict access to authorized entities from explicitly\ntrusted sources only.", + "SubSectionObjective": "Ensure that secure access controls enforce the principle of least privilege to restrict access to authorized entities from explicitly trusted sources only.", "Applicability": [ "tlp-clear", "tlp-green", @@ -7512,14 +5530,14 @@ }, { "Id": "CCC.Core.CN05.AR04", - "Description": "When data is requested from outside the trust perimeter, the\nservice MUST refuse requests from unauthorized entities.", + "Description": "When data is requested from outside the trust perimeter, the service MUST refuse requests from unauthorized entities.", "Attributes": [ { "FamilyName": "Identity and Access Management", - "FamilyDescription": "The Identity and Access Management control family ensures\nthat only trusted and authenticated entities can access\nresources. These controls establish strong authentication,\nenforce multi-factor verification, and restrict access to\napproved sources to prevent unauthorized use or data exfiltration.\n", + "FamilyDescription": "The Identity and Access Management control family ensures that only trusted and authenticated entities can access resources. These controls establish strong authentication, enforce multi-factor verification, and restrict access to approved sources to prevent unauthorized use or data exfiltration. ", "Section": "", "SubSection": "CCC.Core.CN05 Prevent Access from Untrusted Entities", - "SubSectionObjective": "Ensure that secure access controls enforce the principle of least\nprivilege to restrict access to authorized entities from explicitly\ntrusted sources only.", + "SubSectionObjective": "Ensure that secure access controls enforce the principle of least privilege to restrict access to authorized entities from explicitly trusted sources only.", "Applicability": [ "tlp-amber", "tlp-red" @@ -7595,14 +5613,14 @@ }, { "Id": "CCC.Core.CN05.AR05", - "Description": "When any request is made from outside the trust perimeter,\nthe service MUST NOT provide any response that may indicate the\nservice exists.", + "Description": "When any request is made from outside the trust perimeter, the service MUST NOT provide any response that may indicate the service exists.", "Attributes": [ { "FamilyName": "Identity and Access Management", - "FamilyDescription": "The Identity and Access Management control family ensures\nthat only trusted and authenticated entities can access\nresources. These controls establish strong authentication,\nenforce multi-factor verification, and restrict access to\napproved sources to prevent unauthorized use or data exfiltration.\n", + "FamilyDescription": "The Identity and Access Management control family ensures that only trusted and authenticated entities can access resources. These controls establish strong authentication, enforce multi-factor verification, and restrict access to approved sources to prevent unauthorized use or data exfiltration. ", "Section": "CCC.Core.CN05 Prevent Access from Untrusted Entities", "SubSection": "", - "SubSectionObjective": "Ensure that secure access controls enforce the principle of least\nprivilege to restrict access to authorized entities from explicitly\ntrusted sources only.", + "SubSectionObjective": "Ensure that secure access controls enforce the principle of least privilege to restrict access to authorized entities from explicitly trusted sources only.", "Applicability": [ "tlp-red" ], @@ -7673,14 +5691,14 @@ }, { "Id": "CCC.Core.CN05.AR06", - "Description": "When any request is made to the service or a child resource, the\nservice MUST refuse requests from unauthorized entities.", + "Description": "When any request is made to the service or a child resource, the service MUST refuse requests from unauthorized entities.", "Attributes": [ { "FamilyName": "Identity and Access Management", - "FamilyDescription": "The Identity and Access Management control family ensures\nthat only trusted and authenticated entities can access\nresources. These controls establish strong authentication,\nenforce multi-factor verification, and restrict access to\napproved sources to prevent unauthorized use or data exfiltration.\n", + "FamilyDescription": "The Identity and Access Management control family ensures that only trusted and authenticated entities can access resources. These controls establish strong authentication, enforce multi-factor verification, and restrict access to approved sources to prevent unauthorized use or data exfiltration. ", "Section": "CCC.Core.CN05 Prevent Access from Untrusted Entities", "SubSection": "", - "SubSectionObjective": "Ensure that secure access controls enforce the principle of least\nprivilege to restrict access to authorized entities from explicitly\ntrusted sources only.", + "SubSectionObjective": "Ensure that secure access controls enforce the principle of least privilege to restrict access to authorized entities from explicitly trusted sources only.", "Applicability": [ "tlp-green", "tlp-amber", @@ -7757,14 +5775,14 @@ }, { "Id": "CCC.Core.CN04.AR01", - "Description": "When administrative access or configuration change is attempted on\nthe service or a child resource, the service MUST log the client\nidentity, time, and result of the attempt.", + "Description": "When administrative access or configuration change is attempted on the service or a child resource, the service MUST log the client identity, time, and result of the attempt.", "Attributes": [ { "FamilyName": "Logging & Monitoring", - "FamilyDescription": "The Logging & Monitoring control family ensures that access,\nchanges, and security-relevant events are captured, monitored,\nand alerted on in order to provide visibility, support\nincident response, and meet compliance requirements.\n", + "FamilyDescription": "The Logging & Monitoring control family ensures that access, changes, and security-relevant events are captured, monitored, and alerted on in order to provide visibility, support incident response, and meet compliance requirements. ", "Section": "CCC.Core.CN04 Log All Access and Changes", "SubSection": "", - "SubSectionObjective": "Ensure that all access attempts are logged to maintain a detailed\naudit trail for security and compliance purposes.", + "SubSectionObjective": "Ensure that all access attempts are logged to maintain a detailed audit trail for security and compliance purposes.", "Applicability": [ "tlp-clear", "tlp-green", @@ -7819,14 +5837,14 @@ }, { "Id": "CCC.Core.CN04.AR02", - "Description": "When any attempt is made to modify data on the service or a child\nresource, the service MUST log the client identity, time, and\nresult of the attempt.", + "Description": "When any attempt is made to modify data on the service or a child resource, the service MUST log the client identity, time, and result of the attempt.", "Attributes": [ { "FamilyName": "Logging & Monitoring", - "FamilyDescription": "The Logging & Monitoring control family ensures that access,\nchanges, and security-relevant events are captured, monitored,\nand alerted on in order to provide visibility, support\nincident response, and meet compliance requirements.\n", + "FamilyDescription": "The Logging & Monitoring control family ensures that access, changes, and security-relevant events are captured, monitored, and alerted on in order to provide visibility, support incident response, and meet compliance requirements. ", "Section": "CCC.Core.CN04 Log All Access and Changes", "SubSection": "", - "SubSectionObjective": "Ensure that all access attempts are logged to maintain a detailed\naudit trail for security and compliance purposes.", + "SubSectionObjective": "Ensure that all access attempts are logged to maintain a detailed audit trail for security and compliance purposes.", "Applicability": [ "tlp-amber", "tlp-red" @@ -7879,14 +5897,14 @@ }, { "Id": "CCC.Core.CN04.AR03", - "Description": "When any attempt is made to read data on the service or a child\nresource, the service MUST log the client identity, time, and\nresult of the attempt.", + "Description": "When any attempt is made to read data on the service or a child resource, the service MUST log the client identity, time, and result of the attempt.", "Attributes": [ { "FamilyName": "Logging & Monitoring", - "FamilyDescription": "The Logging & Monitoring control family ensures that access,\nchanges, and security-relevant events are captured, monitored,\nand alerted on in order to provide visibility, support\nincident response, and meet compliance requirements.\n", + "FamilyDescription": "The Logging & Monitoring control family ensures that access, changes, and security-relevant events are captured, monitored, and alerted on in order to provide visibility, support incident response, and meet compliance requirements. ", "Section": "CCC.Core.CN04 Log All Access and Changes", "SubSection": "", - "SubSectionObjective": "Ensure that all access attempts are logged to maintain a detailed\naudit trail for security and compliance purposes.", + "SubSectionObjective": "Ensure that all access attempts are logged to maintain a detailed audit trail for security and compliance purposes.", "Applicability": [ "tlp-red" ], @@ -7938,19 +5956,19 @@ }, { "Id": "CCC.Core.CN07.AR01", - "Description": "When enumeration activities are detected, the service MUST publish\nan event to a monitored channel which includes the client\nidentity, time, and nature of the activity.", + "Description": "When enumeration activities are detected, the service MUST publish an event to a monitored channel which includes the client identity, time, and nature of the activity.", "Attributes": [ { "FamilyName": "Logging & Monitoring", - "FamilyDescription": "The Logging & Monitoring control family ensures that access,\nchanges, and security-relevant events are captured, monitored,\nand alerted on in order to provide visibility, support\nincident response, and meet compliance requirements.\n", + "FamilyDescription": "The Logging & Monitoring control family ensures that access, changes, and security-relevant events are captured, monitored, and alerted on in order to provide visibility, support incident response, and meet compliance requirements. ", "Section": "CCC.Core.CN07 Alert on Unusual Enumeration Activity", "SubSection": "", - "SubSectionObjective": "Ensure that logs and associated alerts are generated when\nunusual enumeration activity is detected that may indicate\nreconnaissance activities.", + "SubSectionObjective": "Ensure that logs and associated alerts are generated when unusual enumeration activity is detected that may indicate reconnaissance activities.", "Applicability": [ "tlp-amber", "tlp-red" ], - "Recommendation": "Implement event publication mechanisms and alerts for patterns\nindicative of enumeration activities, such as repeated access\nattempts, requests, or liveness probes. Configure alerts to notify\nsecurity teams of any activities that merit further investigation.\n", + "Recommendation": "Implement event publication mechanisms and alerts for patterns indicative of enumeration activities, such as repeated access attempts, requests, or liveness probes. Configure alerts to notify security teams of any activities that merit further investigation. ", "SectionThreatMappings": [ { "ReferenceId": "CCC", @@ -7996,21 +6014,21 @@ }, { "Id": "CCC.Core.CN07.AR02", - "Description": "When enumeration activities are detected, the service MUST log the\nclient identity, time, and nature of the activity.", + "Description": "When enumeration activities are detected, the service MUST log the client identity, time, and nature of the activity.", "Attributes": [ { "FamilyName": "Logging & Monitoring", - "FamilyDescription": "The Logging & Monitoring control family ensures that access,\nchanges, and security-relevant events are captured, monitored,\nand alerted on in order to provide visibility, support\nincident response, and meet compliance requirements.\n", + "FamilyDescription": "The Logging & Monitoring control family ensures that access, changes, and security-relevant events are captured, monitored, and alerted on in order to provide visibility, support incident response, and meet compliance requirements. ", "Section": "CCC.Core.CN07 Alert on Unusual Enumeration Activity", "SubSection": "", - "SubSectionObjective": "Ensure that logs and associated alerts are generated when\nunusual enumeration activity is detected that may indicate\nreconnaissance activities.", + "SubSectionObjective": "Ensure that logs and associated alerts are generated when unusual enumeration activity is detected that may indicate reconnaissance activities.", "Applicability": [ "tlp-clear", "tlp-green", "tlp-amber", "tlp-red" ], - "Recommendation": "Implement logging mechanisms to capture details of enumeration\nactivities, including client identity, timestamps, and activity\nnature. Retain logs according to organizational policies, and\noccasionally review them for patterns that may indicate\nreconnaissance activities.\n", + "Recommendation": "Implement logging mechanisms to capture details of enumeration activities, including client identity, timestamps, and activity nature. Retain logs according to organizational policies, and occasionally review them for patterns that may indicate reconnaissance activities. ", "SectionThreatMappings": [ { "ReferenceId": "CCC", diff --git a/prowler/providers/aws/aws_regions_by_service.json b/prowler/providers/aws/aws_regions_by_service.json index 1c5ea06b5f..f8e2a9f605 100644 --- a/prowler/providers/aws/aws_regions_by_service.json +++ b/prowler/providers/aws/aws_regions_by_service.json @@ -819,18 +819,6 @@ "aws-us-gov": [] } }, - "apptest": { - "regions": { - "aws": [ - "ap-southeast-2", - "eu-central-1", - "sa-east-1", - "us-east-1" - ], - "aws-cn": [], - "aws-us-gov": [] - } - }, "aps": { "regions": { "aws": [ @@ -8723,6 +8711,7 @@ "ap-southeast-5", "ca-central-1", "eu-central-1", + "eu-central-2", "eu-north-1", "eu-south-2", "eu-west-1", @@ -9207,11 +9196,13 @@ "ap-east-2", "ap-northeast-1", "ap-northeast-2", + "ap-northeast-3", "ap-south-1", "ap-south-2", "ap-southeast-1", "ap-southeast-2", "ap-southeast-3", + "ap-southeast-5", "ap-southeast-7", "ca-central-1", "eu-central-1", @@ -12436,7 +12427,12 @@ "workspaces-instances": { "regions": { "aws": [ - "ap-northeast-2" + "ap-east-1", + "ap-northeast-2", + "ap-southeast-5", + "eu-south-2", + "me-central-1", + "us-east-2" ], "aws-cn": [], "aws-us-gov": [] diff --git a/prowler/providers/aws/services/cloudtrail/cloudtrail_bucket_requires_mfa_delete/cloudtrail_bucket_requires_mfa_delete.metadata.json b/prowler/providers/aws/services/cloudtrail/cloudtrail_bucket_requires_mfa_delete/cloudtrail_bucket_requires_mfa_delete.metadata.json index 1f8ec97e29..536d0070e0 100644 --- a/prowler/providers/aws/services/cloudtrail/cloudtrail_bucket_requires_mfa_delete/cloudtrail_bucket_requires_mfa_delete.metadata.json +++ b/prowler/providers/aws/services/cloudtrail/cloudtrail_bucket_requires_mfa_delete/cloudtrail_bucket_requires_mfa_delete.metadata.json @@ -1,33 +1,38 @@ { "Provider": "aws", "CheckID": "cloudtrail_bucket_requires_mfa_delete", - "CheckTitle": "Ensure the S3 bucket CloudTrail bucket requires MFA delete", + "CheckTitle": "CloudTrail trail S3 bucket has MFA delete enabled", "CheckType": [ - "Software and Configuration Checks", - "Industry and Regulatory Standards", - "CIS AWS Foundations Benchmark" + "Software and Configuration Checks/AWS Security Best Practices", + "Software and Configuration Checks/Industry and Regulatory Standards/AWS Foundational Security Best Practices", + "Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark" ], "ServiceName": "cloudtrail", "SubServiceName": "", - "ResourceIdTemplate": "arn:partition:service:region:account-id:resource-id", + "ResourceIdTemplate": "", "Severity": "medium", "ResourceType": "AwsCloudTrailTrail", - "Description": "Ensure the S3 bucket CloudTrail bucket requires MFA", - "Risk": "If the S3 bucket CloudTrail bucket does not require MFA, it can be deleted by an attacker.", + "Description": "**CloudTrail log buckets** for actively logging trails are evaluated for **MFA Delete** on the associated S3 bucket. The assessment determines whether `MFA Delete` is configured on the in-account log bucket; *if the bucket resides in another account, its configuration should be verified separately*.", + "Risk": "Without **MFA Delete**, stolen or over-privileged credentials can permanently delete log versions or change versioning, compromising log **integrity** and **availability**. This enables attacker cover-ups, hinders **forensics**, and weakens evidence for investigations.", "RelatedUrl": "", + "AdditionalURLs": [ + "https://docs.aws.amazon.com/AmazonS3/latest/userguide/MultiFactorAuthenticationDelete.html", + "https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/CloudTrail/cloudtrail-bucket-mfa-delete-enabled.html" + ], "Remediation": { "Code": { - "CLI": "aws s3api put-bucket-versioning --bucket DOC-EXAMPLE-BUCKET1 --versioning-configuration Status=Enabled,MFADelete=Enabled --mfa \"SERIAL 123456\"", + "CLI": "aws s3api put-bucket-versioning --bucket --versioning-configuration Status=Enabled,MFADelete=Enabled --mfa \" \"", "NativeIaC": "", - "Other": "", + "Other": "1. Sign in to the AWS Management Console as the root user with MFA enabled\n2. Open AWS CloudShell (from the top navigation bar)\n3. Run:\n ```bash\n aws s3api put-bucket-versioning --bucket --versioning-configuration Status=Enabled,MFADelete=Enabled --mfa \" \"\n ```", "Terraform": "" }, "Recommendation": { - "Text": "Configure MFA Delete for the S3 bucket CloudTrail bucket", - "Url": "https://docs.aws.amazon.com/AmazonS3/latest/userguide/MultiFactorAuthenticationDelete.html" + "Text": "Enable `MFA Delete` on the CloudTrail log bucket with versioning enabled. Enforce **least privilege** so only tightly controlled identities can delete or alter logs, and require MFA for such actions. Apply **defense in depth** using a dedicated logging account and log file integrity validation.", + "Url": "https://hub.prowler.com/check/cloudtrail_bucket_requires_mfa_delete" } }, "Categories": [ + "identity-access", "forensics-ready" ], "DependsOn": [], diff --git a/prowler/providers/aws/services/cloudtrail/cloudtrail_cloudwatch_logging_enabled/cloudtrail_cloudwatch_logging_enabled.metadata.json b/prowler/providers/aws/services/cloudtrail/cloudtrail_cloudwatch_logging_enabled/cloudtrail_cloudwatch_logging_enabled.metadata.json index 9f9339038f..00c76fcfba 100644 --- a/prowler/providers/aws/services/cloudtrail/cloudtrail_cloudwatch_logging_enabled/cloudtrail_cloudwatch_logging_enabled.metadata.json +++ b/prowler/providers/aws/services/cloudtrail/cloudtrail_cloudwatch_logging_enabled/cloudtrail_cloudwatch_logging_enabled.metadata.json @@ -1,35 +1,39 @@ { "Provider": "aws", "CheckID": "cloudtrail_cloudwatch_logging_enabled", - "CheckTitle": "Ensure CloudTrail trails are integrated with CloudWatch Logs", + "CheckTitle": "CloudTrail trail has delivered logs to CloudWatch Logs in the last 24 hours", "CheckType": [ - "Software and Configuration Checks", - "Industry and Regulatory Standards", - "CIS AWS Foundations Benchmark" + "Software and Configuration Checks/AWS Security Best Practices", + "Software and Configuration Checks/Industry and Regulatory Standards/AWS Foundational Security Best Practices", + "Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark" ], "ServiceName": "cloudtrail", "SubServiceName": "", - "ResourceIdTemplate": "arn:partition:service:region:account-id:resource-id", + "ResourceIdTemplate": "", "Severity": "low", "ResourceType": "AwsCloudTrailTrail", - "Description": "Ensure CloudTrail trails are integrated with CloudWatch Logs", - "Risk": "Sending CloudTrail logs to CloudWatch Logs will facilitate real-time and historic activity logging based on user, API, resource, and IP address, and provides opportunity to establish alarms and notifications for anomalous or sensitivity account activity.", + "Description": "**CloudTrail trails** are configured to send events to **CloudWatch Logs**, and show recent delivery within the last `24h`. Trails without integration or without recent CloudWatch delivery are identified, across single-Region and multi-Region trails.", + "Risk": "Missing or stale CloudWatch delivery weakens visibility and delays detection, impacting confidentiality and integrity. Adversaries can:\n- Hide **privilege escalation**\n- Perform unauthorized **resource changes**\n- Exfiltrate data via API misuse", "RelatedUrl": "", + "AdditionalURLs": [ + "https://docs.prowler.com/checks/aws/logging-policies/logging_4#aws-console", + "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/send-cloudtrail-events-to-cloudwatch-logs.html" + ], "Remediation": { "Code": { - "CLI": "aws cloudtrail update-trail --name --cloudwatch-logs-log-group- arn --cloudwatch-logs-role-arn ", - "NativeIaC": "", - "Other": "https://docs.prowler.com/checks/aws/logging-policies/logging_4#aws-console", - "Terraform": "" + "CLI": "aws cloudtrail update-trail --name --cloud-watch-logs-log-group-arn --cloud-watch-logs-role-arn ", + "NativeIaC": "```yaml\n# CloudFormation: enable CloudTrail delivery to CloudWatch Logs\nResources:\n :\n Type: AWS::CloudTrail::Trail\n Properties:\n S3BucketName: \"\"\n CloudWatchLogsLogGroupArn: \"\" # CRITICAL: sends CloudTrail events to CloudWatch Logs\n CloudWatchLogsRoleArn: \"\" # CRITICAL: role CloudTrail assumes to deliver events\n```", + "Other": "1. In AWS Console, go to CloudTrail > Trails and select the trail\n2. In the CloudWatch Logs section, click Edit\n3. Set CloudWatch Logs to Enabled\n4. Choose an existing Log group (or create new) and select an IAM role with permissions for CreateLogStream/PutLogEvents\n5. Click Save changes\n6. After a few minutes, verify events appear in the chosen CloudWatch Logs log group", + "Terraform": "```hcl\n# Terraform: enable CloudTrail delivery to CloudWatch Logs\nresource \"aws_cloudtrail\" \"\" {\n name = \"\"\n s3_bucket_name = \"\"\n cloud_watch_logs_group_arn = \"\" # CRITICAL: sends CloudTrail events to CloudWatch Logs\n cloud_watch_logs_role_arn = \"\" # CRITICAL: role CloudTrail assumes to deliver events\n}\n```" }, "Recommendation": { - "Text": "Validate that the trails in CloudTrail have an arn set in the CloudWatchLogsLogGroupArn property.", - "Url": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/send-cloudtrail-events-to-cloudwatch-logs.html" + "Text": "Integrate every trail with **CloudWatch Logs** and maintain continuous, near-real-time delivery. Enforce **least privilege** on the delivery role, prefer **multi-Region** coverage, and implement **metric filters and alerts** for sensitive actions. Centralize retention to support **defense in depth**.", + "Url": "https://hub.prowler.com/check/cloudtrail_cloudwatch_logging_enabled" } }, "Categories": [ - "forensics-ready", - "logging" + "logging", + "forensics-ready" ], "DependsOn": [], "RelatedTo": [], diff --git a/prowler/providers/aws/services/cloudtrail/cloudtrail_insights_exist/cloudtrail_insights_exist.metadata.json b/prowler/providers/aws/services/cloudtrail/cloudtrail_insights_exist/cloudtrail_insights_exist.metadata.json index 1bff51d44e..9ca93b1bc7 100644 --- a/prowler/providers/aws/services/cloudtrail/cloudtrail_insights_exist/cloudtrail_insights_exist.metadata.json +++ b/prowler/providers/aws/services/cloudtrail/cloudtrail_insights_exist/cloudtrail_insights_exist.metadata.json @@ -1,34 +1,39 @@ { "Provider": "aws", "CheckID": "cloudtrail_insights_exist", - "CheckTitle": "Ensure CloudTrail Insight is enabled", + "CheckTitle": "CloudTrail trail has Insights enabled", "CheckType": [ - "Software and Configuration Checks", - "Industry and Regulatory Standards", - "CIS AWS Foundations Benchmark" + "Software and Configuration Checks/AWS Security Best Practices/Runtime Behavior Analysis", + "Software and Configuration Checks/Industry and Regulatory Standards/AWS Foundational Security Best Practices", + "Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark" ], "ServiceName": "cloudtrail", "SubServiceName": "", - "ResourceIdTemplate": "arn:partition:service:region:account-id:resource-id", + "ResourceIdTemplate": "", "Severity": "low", "ResourceType": "AwsCloudTrailTrail", - "Description": "Ensure CloudTrail Insight is enabled", - "Risk": "CloudTrail Insights provides a powerful way to search and analyze CloudTrail log data using pre-built queries and machine learning algorithms. This can help you to identify potential security threats and suspicious activity in near real-time, such as unauthorized access attempts, policy changes, or resource modifications.", + "Description": "**CloudTrail trails** that are logging are evaluated for **Insights** via `insight selectors`, which enable anomaly detection on management-event patterns (API call and error rates). The finding pinpoints logging trails where these selectors are missing.", + "Risk": "Without **Insights**, abnormal API call or error rates can go unnoticed, delaying detection of credential abuse, privilege escalation, or runaway automation. Attackers may rapidly alter policies, delete resources, or exfiltrate data before response, impacting confidentiality and availability.", "RelatedUrl": "", + "AdditionalURLs": [ + "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/logging-insights-events-with-cloudtrail.html", + "https://awscli.amazonaws.com/v2/documentation/api/2.18.18/reference/cloudtrail/put-insight-selectors.html", + "https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudtrail" + ], "Remediation": { "Code": { - "CLI": "", - "NativeIaC": "", - "Other": "", - "Terraform": "" + "CLI": "aws cloudtrail put-insight-selectors --trail-name --insight-selectors '[{\"InsightType\":\"ApiCallRateInsight\"}]'", + "NativeIaC": "```yaml\nResources:\n :\n Type: AWS::CloudTrail::Trail\n Properties:\n TrailName: \n S3BucketName: \n IsLogging: true\n InsightSelectors:\n - InsightType: ApiCallRateInsight # Critical fix: enables CloudTrail Insights on the trail\n```", + "Other": "1. In the AWS Console, go to CloudTrail > Trails\n2. Select the trail that is logging\n3. Click Edit on the CloudTrail Insights section\n4. Enable Insights and select API call rate (or Error rate)\n5. Save changes", + "Terraform": "```hcl\nresource \"aws_cloudtrail\" \"\" {\n name = \"\"\n s3_bucket_name = \"\"\n enable_logging = true\n\n insight_selector {\n insight_type = \"ApiCallRateInsight\" # Critical fix: enables CloudTrail Insights on the trail\n }\n}\n```" }, "Recommendation": { - "Text": "Enable CloudTrail Insight", - "Url": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/logging-insights-events-with-cloudtrail.html" + "Text": "Enable **CloudTrail Insights** on all logging trails (ideally all-Region or organization trails). Activate both `ApiCallRateInsight` and `ApiErrorRateInsight`. Integrate alerts with monitoring and review anomalies regularly. Apply **defense in depth** and least privilege to reduce potential blast radius.", + "Url": "https://hub.prowler.com/check/cloudtrail_insights_exist" } }, "Categories": [ - "forensics-ready" + "threat-detection" ], "DependsOn": [], "RelatedTo": [], diff --git a/prowler/providers/aws/services/cloudtrail/cloudtrail_kms_encryption_enabled/cloudtrail_kms_encryption_enabled.metadata.json b/prowler/providers/aws/services/cloudtrail/cloudtrail_kms_encryption_enabled/cloudtrail_kms_encryption_enabled.metadata.json index d20a08ad78..25e995b18f 100644 --- a/prowler/providers/aws/services/cloudtrail/cloudtrail_kms_encryption_enabled/cloudtrail_kms_encryption_enabled.metadata.json +++ b/prowler/providers/aws/services/cloudtrail/cloudtrail_kms_encryption_enabled/cloudtrail_kms_encryption_enabled.metadata.json @@ -1,34 +1,39 @@ { "Provider": "aws", "CheckID": "cloudtrail_kms_encryption_enabled", - "CheckTitle": "Ensure CloudTrail logs are encrypted at rest using KMS CMKs", + "CheckTitle": "CloudTrail trail logs are encrypted at rest with a KMS key", "CheckType": [ - "Software and Configuration Checks", - "Industry and Regulatory Standards", - "CIS AWS Foundations Benchmark" + "Software and Configuration Checks/AWS Security Best Practices", + "Software and Configuration Checks/Industry and Regulatory Standards/AWS Foundational Security Best Practices", + "Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark" ], "ServiceName": "cloudtrail", "SubServiceName": "", - "ResourceIdTemplate": "arn:partition:service:region:account-id:resource-id", + "ResourceIdTemplate": "", "Severity": "medium", "ResourceType": "AwsCloudTrailTrail", - "Description": "Ensure CloudTrail logs are encrypted at rest using KMS CMKs", - "Risk": "By default, the log files delivered by CloudTrail to your bucket are encrypted by Amazon server-side encryption with Amazon S3-managed encryption keys (SSE-S3). To provide a security layer that is directly manageable, you can instead use server-side encryption with AWS KMS–managed keys (SSE-KMS) for your CloudTrail log files.", + "Description": "**AWS CloudTrail trails** are evaluated for use of **SSE-KMS** with a customer-managed KMS key to encrypt delivered log files at rest in S3. Trails without a configured KMS key are identified. *Applies to single-Region and multi-Region trails.*", + "Risk": "Absent a **customer-managed KMS key**, log protection relies only on storage permissions. Bucket misconfigurations or stolen credentials can expose audit data, aiding evasion and lateral movement. Missing key-level controls, rotation, and usage audit weaken **confidentiality** and **forensic integrity**.", "RelatedUrl": "", + "AdditionalURLs": [ + "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/encrypting-cloudtrail-log-files-with-aws-kms.html", + "https://trendmicro.com/cloudoneconformity/knowledge-base/aws/CloudTrail/cloudtrail-logs-encrypted.html", + "https://www.stream.security/rules/ensure-cloudtrail-logs-are-encrypted-at-rest", + "https://www.clouddefense.ai/compliance-rules/cis-v130/logging/cis-v130-3-7" + ], "Remediation": { "Code": { - "CLI": "aws cloudtrail update-trail --name --kms-id aws kms put-key-policy --key-id --policy ", - "NativeIaC": "https://docs.prowler.com/checks/aws/logging-policies/logging_7#fix---buildtime", - "Other": "", - "Terraform": "" + "CLI": "aws cloudtrail update-trail --name --kms-key-id ", + "NativeIaC": "```yaml\n# CloudFormation: enable KMS encryption for an existing/new CloudTrail\nResources:\n :\n Type: AWS::CloudTrail::Trail\n Properties:\n S3BucketName: \n KmsKeyId: # Critical: sets the KMS key to encrypt CloudTrail logs at rest\n```", + "Other": "1. In the AWS Console, go to CloudTrail > Trails\n2. Select the trail , click Edit\n3. Under Log file encryption, choose Use a KMS key and select \n4. Click Save changes", + "Terraform": "```hcl\n# Enable KMS encryption for CloudTrail\nresource \"aws_cloudtrail\" \"\" {\n name = \"\"\n s3_bucket_name = \"\"\n kms_key_id = \"\" # Critical: uses this KMS key to encrypt CloudTrail logs\n}\n```" }, "Recommendation": { - "Text": "This approach has the following advantages: You can create and manage the CMK encryption keys yourself. You can use a single CMK to encrypt and decrypt log files for multiple accounts across all regions. You have control over who can use your key for encrypting and decrypting CloudTrail log files. You can assign permissions for the key to the users. You have enhanced security.", - "Url": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/encrypting-cloudtrail-log-files-with-aws-kms.html" + "Text": "Enable **SSE-KMS** on every trail using a **customer-managed KMS key**. Apply **least privilege** so only authorized roles can `Decrypt`, and enforce **separation of duties** between key admins and log readers. Rotate keys and monitor key usage to provide **defense in depth** for CloudTrail data.", + "Url": "https://hub.prowler.com/check/cloudtrail_kms_encryption_enabled" } }, "Categories": [ - "forensics-ready", "encryption" ], "DependsOn": [], diff --git a/prowler/providers/aws/services/cloudtrail/cloudtrail_log_file_validation_enabled/cloudtrail_log_file_validation_enabled.metadata.json b/prowler/providers/aws/services/cloudtrail/cloudtrail_log_file_validation_enabled/cloudtrail_log_file_validation_enabled.metadata.json index 95e0fdd478..4ea5fa8f23 100644 --- a/prowler/providers/aws/services/cloudtrail/cloudtrail_log_file_validation_enabled/cloudtrail_log_file_validation_enabled.metadata.json +++ b/prowler/providers/aws/services/cloudtrail/cloudtrail_log_file_validation_enabled/cloudtrail_log_file_validation_enabled.metadata.json @@ -1,33 +1,40 @@ { "Provider": "aws", "CheckID": "cloudtrail_log_file_validation_enabled", - "CheckTitle": "Ensure CloudTrail log file validation is enabled", + "CheckTitle": "CloudTrail trail has log file validation enabled", "CheckType": [ - "Software and Configuration Checks", - "Industry and Regulatory Standards", - "CIS AWS Foundations Benchmark" + "Software and Configuration Checks/AWS Security Best Practices", + "Software and Configuration Checks/Industry and Regulatory Standards/AWS Foundational Security Best Practices", + "Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark" ], "ServiceName": "cloudtrail", "SubServiceName": "", - "ResourceIdTemplate": "arn:partition:service:region:account-id:resource-id", + "ResourceIdTemplate": "", "Severity": "medium", "ResourceType": "AwsCloudTrailTrail", - "Description": "Ensure CloudTrail log file validation is enabled", - "Risk": "Enabling log file validation will provide additional integrity checking of CloudTrail logs. ", + "Description": "**AWS CloudTrail trails** are evaluated for **log file integrity validation** being enabled (`LogFileValidationEnabled`).\n\nWhen enabled, CloudTrail generates signed digest files to verify that S3-delivered log files remain unchanged.", + "Risk": "Without validation, adversaries can alter, forge, or delete audit entries without detection, compromising log **integrity** and non-repudiation.\n\nThis impairs investigations, enables alert evasion, and obscures unauthorized changes across regions or accounts.", "RelatedUrl": "", + "AdditionalURLs": [ + "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-log-file-validation-intro.html", + "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-log-file-validation-enabling.html", + "https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/CloudTrail/cloudtrail-log-file-integrity-validation.html", + "https://deepwiki.com/acantril/learn-cantrill-io-labs/7.1-cloudtrail-log-file-integrity" + ], "Remediation": { "Code": { - "CLI": "aws cloudtrail update-trail --name --enable-log-file-validation", - "NativeIaC": "https://docs.prowler.com/checks/aws/logging-policies/logging_2#cloudformation", - "Other": "", - "Terraform": "https://docs.prowler.com/checks/aws/logging-policies/logging_2#terraform" + "CLI": "aws cloudtrail update-trail --name --enable-log-file-validation", + "NativeIaC": "```yaml\n# CloudFormation: Enable log file validation on a CloudTrail trail\nResources:\n :\n Type: AWS::CloudTrail::Trail\n Properties:\n S3BucketName: \n EnableLogFileValidation: true # Critical: enables integrity validation for delivered log files\n```", + "Other": "1. Open the AWS Console and go to CloudTrail\n2. Click Trails and select \n3. Click Edit\n4. In Additional/Advanced settings, check Enable log file validation\n5. Click Save changes", + "Terraform": "```hcl\n# Enable log file validation on a CloudTrail trail\nresource \"aws_cloudtrail\" \"\" {\n name = \"\"\n s3_bucket_name = \"\"\n enable_log_file_validation = true # Critical: ensures CloudTrail writes signed digests to detect tampering\n}\n```" }, "Recommendation": { - "Text": "Ensure LogFileValidationEnabled is set to true for each trail.", - "Url": "http://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-log-filevalidation-enabling.html" + "Text": "Enable **log file integrity validation** on all trails (`LogFileValidationEnabled=true`).\n\nEnforce **least privilege** on the logs bucket, retain and protect digest files (e.g., S3 Object Lock/MFA Delete), and monitor validation results to support **defense in depth**.", + "Url": "https://hub.prowler.com/check/cloudtrail_log_file_validation_enabled" } }, "Categories": [ + "logging", "forensics-ready" ], "DependsOn": [], diff --git a/prowler/providers/aws/services/cloudtrail/cloudtrail_logs_s3_bucket_access_logging_enabled/cloudtrail_logs_s3_bucket_access_logging_enabled.metadata.json b/prowler/providers/aws/services/cloudtrail/cloudtrail_logs_s3_bucket_access_logging_enabled/cloudtrail_logs_s3_bucket_access_logging_enabled.metadata.json index 1dba458d47..6314d80dbd 100644 --- a/prowler/providers/aws/services/cloudtrail/cloudtrail_logs_s3_bucket_access_logging_enabled/cloudtrail_logs_s3_bucket_access_logging_enabled.metadata.json +++ b/prowler/providers/aws/services/cloudtrail/cloudtrail_logs_s3_bucket_access_logging_enabled/cloudtrail_logs_s3_bucket_access_logging_enabled.metadata.json @@ -1,33 +1,38 @@ { "Provider": "aws", "CheckID": "cloudtrail_logs_s3_bucket_access_logging_enabled", - "CheckTitle": "Ensure S3 bucket access logging is enabled on the CloudTrail S3 bucket", + "CheckTitle": "CloudTrail trail destination S3 bucket has access logging enabled", "CheckType": [ - "Software and Configuration Checks", - "Industry and Regulatory Standards", - "CIS AWS Foundations Benchmark" + "Software and Configuration Checks/AWS Security Best Practices", + "Software and Configuration Checks/Industry and Regulatory Standards/AWS Foundational Security Best Practices", + "Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark" ], "ServiceName": "cloudtrail", "SubServiceName": "", - "ResourceIdTemplate": "arn:partition:service:region:account-id:resource-id", + "ResourceIdTemplate": "", "Severity": "medium", "ResourceType": "AwsCloudTrailTrail", - "Description": "Ensure S3 bucket access logging is enabled on the CloudTrail S3 bucket", - "Risk": "Server access logs can assist you in security and access audits, help you learn about your customer base, and understand your Amazon S3 bill.", + "Description": "CloudTrail trails deliver logs to an S3 bucket; this evaluates whether that bucket has **S3 server access logging** enabled to record requests against it.\n\n*If the destination bucket is outside the account or audit scope, a manual review is indicated.*", + "Risk": "Without access logging on the CloudTrail logs bucket, access and changes to log files lack an independent audit trail. Attackers could read, delete, or replace logs without attribution, undermining **log confidentiality** and **integrity**, and slowing **incident response**.", "RelatedUrl": "", + "AdditionalURLs": [ + "https://docs.aws.amazon.com/securityhub/latest/userguide/cloudtrail-controls.html", + "https://docs.aws.amazon.com/AmazonS3/latest/dev/security-best-practices.html" + ], "Remediation": { "Code": { - "CLI": "", - "NativeIaC": "", - "Other": "https://docs.prowler.com/checks/aws/logging-policies/logging_6#aws-console", - "Terraform": "" + "CLI": "aws s3api put-bucket-logging --bucket --bucket-logging-status \"{\\\"LoggingEnabled\\\":{\\\"TargetBucket\\\":\\\"\\\"}}\"", + "NativeIaC": "```yaml\n# CloudFormation: enable S3 access logging on the CloudTrail destination bucket\nResources:\n :\n Type: AWS::S3::Bucket\n\n :\n Type: AWS::S3::Bucket\n Properties:\n LoggingConfiguration:\n DestinationBucketName: !Ref # Critical: turns on server access logging to this destination bucket\n # This enables access logging so the check passes\n```", + "Other": "1. In the AWS Console, go to S3 and open the bucket used by your CloudTrail trail\n2. Select the Properties tab\n3. In Server access logging, click Edit\n4. Enable logging and choose a different destination S3 bucket for the logs\n5. Click Save changes", + "Terraform": "```hcl\n# Enable access logging on the CloudTrail S3 bucket\nresource \"aws_s3_bucket\" \"\" {\n bucket = \"\"\n}\n\nresource \"aws_s3_bucket\" \"\" {\n bucket = \"\"\n}\n\nresource \"aws_s3_bucket_logging\" \"\" {\n bucket = aws_s3_bucket..id\n target_bucket = aws_s3_bucket..id # Critical: enables server access logging to the target bucket\n}\n```" }, "Recommendation": { - "Text": "Ensure that S3 buckets have Logging enabled. CloudTrail data events can be used in place of S3 bucket logging. If that is the case, this finding can be considered a false positive.", - "Url": "https://docs.aws.amazon.com/AmazonS3/latest/dev/security-best-practices.html" + "Text": "Enable **S3 server access logging** on the CloudTrail logs bucket and write logs to a separate, tightly controlled bucket. Apply **least privilege**, enable **versioning**, and consider **Object Lock** to deter tampering. Centralize monitoring to support defense-in-depth and rapid investigation.", + "Url": "https://hub.prowler.com/check/cloudtrail_logs_s3_bucket_access_logging_enabled" } }, "Categories": [ + "logging", "forensics-ready" ], "DependsOn": [], diff --git a/prowler/providers/aws/services/cloudtrail/cloudtrail_logs_s3_bucket_is_not_publicly_accessible/cloudtrail_logs_s3_bucket_is_not_publicly_accessible.metadata.json b/prowler/providers/aws/services/cloudtrail/cloudtrail_logs_s3_bucket_is_not_publicly_accessible/cloudtrail_logs_s3_bucket_is_not_publicly_accessible.metadata.json index 049820b5c5..1b0d76462b 100644 --- a/prowler/providers/aws/services/cloudtrail/cloudtrail_logs_s3_bucket_is_not_publicly_accessible/cloudtrail_logs_s3_bucket_is_not_publicly_accessible.metadata.json +++ b/prowler/providers/aws/services/cloudtrail/cloudtrail_logs_s3_bucket_is_not_publicly_accessible/cloudtrail_logs_s3_bucket_is_not_publicly_accessible.metadata.json @@ -1,37 +1,45 @@ { "Provider": "aws", "CheckID": "cloudtrail_logs_s3_bucket_is_not_publicly_accessible", - "CheckTitle": "Ensure the S3 bucket CloudTrail logs is not publicly accessible", + "CheckTitle": "CloudTrail trail S3 bucket is not publicly accessible", "CheckType": [ - "Software and Configuration Checks", - "Industry and Regulatory Standards", - "CIS AWS Foundations Benchmark" + "Software and Configuration Checks/AWS Security Best Practices/Network Reachability", + "Industry and Regulatory Standards/AWS Foundational Security Best Practices", + "Industry and Regulatory Standards/CIS AWS Foundations Benchmark", + "Effects/Data Exposure" ], "ServiceName": "cloudtrail", "SubServiceName": "", - "ResourceIdTemplate": "arn:partition:service:region:account-id:resource-id", + "ResourceIdTemplate": "", "Severity": "critical", - "ResourceType": "AwsCloudTrailTrail", - "Description": "Ensure the S3 bucket CloudTrail logs to is not publicly accessible", - "Risk": "Allowing public access to CloudTrail log content may aid an adversary in identifying weaknesses in the affected accounts use or configuration.", + "ResourceType": "AwsS3Bucket", + "Description": "CloudTrail log destination **S3 buckets** are inspected for ACL grants that expose data to the public `AllUsers` group.\n\nBuckets hosted in other accounts are flagged for out-of-scope review.", + "Risk": "Exposed CloudTrail logs erode **confidentiality** and **integrity**.\n\nAdversaries can harvest API activity to map accounts, roles, and keys, enabling **reconnaissance** and evasion. If write is allowed, logs can be **poisoned** or deleted, thwarting investigations and compromising incident timelines.", "RelatedUrl": "", + "AdditionalURLs": [ + "https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/CloudTrail/cloudtrail-bucket-publicly-accessible.html", + "https://docs.aws.amazon.com/AmazonS3/latest/userguide/access-control-block-public-access.html", + "https://docs.aws.amazon.com/config/latest/developerguide/cloudtrail-s3-bucket-public-access-prohibited.html", + "https://docs.panther.com/alerts/alert-runbooks/built-in-policies/aws-cloudtrail-logs-s3-bucket-not-publicly-accessible" + ], "Remediation": { "Code": { - "CLI": "", - "NativeIaC": "", - "Other": "https://docs.prowler.com/checks/aws/logging-policies/logging_3#aws-console", - "Terraform": "" + "CLI": "aws s3api put-bucket-acl --bucket --acl private", + "NativeIaC": "```yaml\n# CloudFormation: ensure the CloudTrail S3 bucket ACL is not public\nResources:\n CloudTrailLogsBucket:\n Type: AWS::S3::Bucket\n Properties:\n BucketName: \n AccessControl: Private # CRITICAL: sets bucket ACL to private, removing any AllUsers (public) grants\n```", + "Other": "1. Open the AWS S3 Console\n2. Select the bucket used by CloudTrail\n3. Go to Permissions > Access control list (ACL)\n4. Click Edit under Public access, remove any grants to \"Everyone (public access)\" (uncheck Read/Write)\n5. Save changes", + "Terraform": "```hcl\n# Ensure the CloudTrail S3 bucket ACL is private\nresource \"aws_s3_bucket_acl\" \"fix_cloudtrail_logs_bucket\" {\n bucket = \"\"\n acl = \"private\" # CRITICAL: removes any public (AllUsers) ACL grants\n}\n```" }, "Recommendation": { - "Text": "Analyze Bucket policy to validate appropriate permissions. Ensure the AllUsers principal is not granted privileges. Ensure the AuthenticatedUsers principal is not granted privileges.", - "Url": "https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_principal.html" + "Text": "Apply **least privilege** to the log bucket:\n- Enable S3 `Block Public Access` (account and bucket)\n- Remove `AllUsers`/`AuthenticatedUsers` ACLs; avoid wildcard principals\n- Permit only CloudTrail and constrain with `aws:SourceArn`\n\nUse a dedicated private bucket and monitor for permission changes.", + "Url": "https://hub.prowler.com/check/cloudtrail_logs_s3_bucket_is_not_publicly_accessible" } }, "Categories": [ - "forensics-ready", "internet-exposed" ], - "DependsOn": [], + "DependsOn": [ + "s3_bucket_public_access" + ], "RelatedTo": [], "Notes": "" } diff --git a/prowler/providers/aws/services/cloudtrail/cloudtrail_multi_region_enabled/cloudtrail_multi_region_enabled.metadata.json b/prowler/providers/aws/services/cloudtrail/cloudtrail_multi_region_enabled/cloudtrail_multi_region_enabled.metadata.json index 4ec89226eb..3209e88e73 100644 --- a/prowler/providers/aws/services/cloudtrail/cloudtrail_multi_region_enabled/cloudtrail_multi_region_enabled.metadata.json +++ b/prowler/providers/aws/services/cloudtrail/cloudtrail_multi_region_enabled/cloudtrail_multi_region_enabled.metadata.json @@ -1,33 +1,37 @@ { "Provider": "aws", "CheckID": "cloudtrail_multi_region_enabled", - "CheckTitle": "Ensure CloudTrail is enabled in all regions", + "CheckTitle": "Region has at least one CloudTrail trail logging", "CheckType": [ - "Software and Configuration Checks", - "Industry and Regulatory Standards", - "CIS AWS Foundations Benchmark" + "Software and Configuration Checks/AWS Security Best Practices", + "Software and Configuration Checks/Industry and Regulatory Standards/AWS Foundational Security Best Practices", + "Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark" ], "ServiceName": "cloudtrail", "SubServiceName": "", - "ResourceIdTemplate": "arn:partition:service:region:account-id:resource-id", + "ResourceIdTemplate": "", "Severity": "high", "ResourceType": "AwsCloudTrailTrail", - "Description": "Ensure CloudTrail is enabled in all regions", - "Risk": "AWS CloudTrail is a web service that records AWS API calls for your account and delivers log files to you. The recorded information includes the identity of the API caller, the time of the API call, the source IP address of the API caller, the request parameters, and the response elements returned by the AWS service.", + "Description": "**AWS CloudTrail** has at least one trail with `logging` enabled in every region. A **multi-region trail** or a regional trail counts for coverage in that region.", + "Risk": "Missing coverage in any region creates **visibility gaps**.\n\nAttackers can use lesser-monitored regions to run API actions, hide **unauthorized changes**, and exfiltrate data without audit trails, weakening **detective controls**, hindering **forensics**, and delaying response (confidentiality and integrity).", "RelatedUrl": "", + "AdditionalURLs": [ + "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrailconcepts.html#cloudtrail-concepts-management-events" + ], "Remediation": { "Code": { - "CLI": "aws cloudtrail create-trail --name --bucket-name --is-multi-region-trail aws cloudtrail update-trail --name --is-multi-region-trail ", - "NativeIaC": "https://docs.prowler.com/checks/aws/logging-policies/logging_1#cloudformation", - "Other": "https://docs.prowler.com/checks/aws/logging-policies/logging_1#aws-console", - "Terraform": "https://docs.prowler.com/checks/aws/logging-policies/logging_1#terraform" + "CLI": "", + "NativeIaC": "```yaml\n# CloudFormation: Create a multi-region CloudTrail and start logging\nResources:\n :\n Type: AWS::CloudTrail::Trail\n Properties:\n TrailName: \n S3BucketName: \n IsMultiRegionTrail: true # Critical: applies the trail to all regions\n IsLogging: true # Critical: ensures the trail is logging\n```", + "Other": "1. In the AWS Console, go to CloudTrail > Trails\n2. If no trail exists: Click Create trail, enter a name, choose an S3 bucket, set Apply trail to all regions = Yes, then Create (logging starts)\n3. If a trail exists: Select it, click Edit, set Apply trail to all regions = Yes, Save\n4. If Status shows Not logging, click Start logging", + "Terraform": "```hcl\n# Terraform: Multi-region CloudTrail with logging enabled\nresource \"aws_cloudtrail\" \"\" {\n name = \"\"\n s3_bucket_name = \"\"\n\n is_multi_region_trail = true # Critical: applies the trail to all regions\n enable_logging = true # Critical: ensures the trail is logging\n}\n```" }, "Recommendation": { - "Text": "Ensure Logging is set to ON on all regions (even if they are not being used at the moment.", - "Url": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrailconcepts.html#cloudtrail-concepts-management-events" + "Text": "Use a **multi-region CloudTrail trail** or per-region trails so `logging` is active in every region, including unused ones.\n\nCentralize logs, enforce **least privilege** to log stores, and add **defense-in-depth** with encryption, integrity validation, and retention. Continuously monitor trail health to catch gaps.", + "Url": "https://hub.prowler.com/check/cloudtrail_multi_region_enabled" } }, "Categories": [ + "logging", "forensics-ready" ], "DependsOn": [], diff --git a/prowler/providers/aws/services/cloudtrail/cloudtrail_multi_region_enabled_logging_management_events/cloudtrail_multi_region_enabled_logging_management_events.metadata.json b/prowler/providers/aws/services/cloudtrail/cloudtrail_multi_region_enabled_logging_management_events/cloudtrail_multi_region_enabled_logging_management_events.metadata.json index b4b0978ffe..babf6e85b4 100644 --- a/prowler/providers/aws/services/cloudtrail/cloudtrail_multi_region_enabled_logging_management_events/cloudtrail_multi_region_enabled_logging_management_events.metadata.json +++ b/prowler/providers/aws/services/cloudtrail/cloudtrail_multi_region_enabled_logging_management_events/cloudtrail_multi_region_enabled_logging_management_events.metadata.json @@ -1,31 +1,38 @@ { "Provider": "aws", "CheckID": "cloudtrail_multi_region_enabled_logging_management_events", - "CheckTitle": "Ensure CloudTrail logging management events in All Regions", + "CheckTitle": "CloudTrail trail logs management events for read and write operations", "CheckType": [ - "CIS AWS Foundations Benchmark" + "Software and Configuration Checks/AWS Security Best Practices", + "Software and Configuration Checks/Industry and Regulatory Standards/AWS Foundational Security Best Practices", + "Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark" ], "ServiceName": "cloudtrail", "SubServiceName": "", - "ResourceIdTemplate": "arn:partition:service:region:account-id:resource-id", + "ResourceIdTemplate": "", "Severity": "low", "ResourceType": "AwsCloudTrailTrail", - "Description": "Ensure CloudTrail logging management events in All Regions", - "Risk": "AWS CloudTrail enables governance, compliance, operational auditing, and risk auditing of your AWS account. To meet FTR requirements, you must have management events enabled for all AWS accounts and in all regions and aggregate these logs into an Amazon Simple Storage Service (Amazon S3) bucket owned by a separate AWS account.", - "RelatedUrl": "https://docs.prowler.com/checks/aws/logging-policies/logging_14", + "Description": "**CloudTrail trails** record **management events** (`read` and `write`) in every AWS region and are actively logging, using a multi-region trail or per-region coverage.", + "Risk": "Without region-wide management event logging, changes to identities, networking, and audit settings can go untracked.\n\nAdversaries can operate in overlooked regions to create resources, modify permissions, or disable logging, undermining **integrity**, **confidentiality**, and incident response.", + "RelatedUrl": "", + "AdditionalURLs": [ + "https://docs.prowler.com/checks/aws/logging-policies/logging_14#terraform", + "https://docs.prowler.com/checks/aws/logging-policies/logging_14" + ], "Remediation": { "Code": { - "CLI": "aws cloudtrail update-trail --name --is-multi-region-trail", - "NativeIaC": "", - "Other": "https://docs.prowler.com/checks/aws/logging-policies/logging_14", - "Terraform": "https://docs.prowler.com/checks/aws/logging-policies/logging_14#terraform" + "CLI": "", + "NativeIaC": "```yaml\n# CloudFormation: enable multi-region and log management events (read & write)\nResources:\n :\n Type: AWS::CloudTrail::Trail\n Properties:\n S3BucketName: \n IsMultiRegionTrail: true # CRITICAL: apply the trail to all regions\n EventSelectors:\n - IncludeManagementEvents: true # CRITICAL: log management events\n ReadWriteType: All # CRITICAL: log both read and write\n```", + "Other": "1. In the AWS Console, go to CloudTrail > Trails and select your trail\n2. Click Edit\n3. Set Apply trail to all regions to Yes\n4. Under Management events, set Read/write events to All\n5. Click Save changes\n6. If Logging is Off, click Start logging", + "Terraform": "```hcl\n# Terraform: enable multi-region and log management events (read & write)\nresource \"aws_cloudtrail\" \"\" {\n name = \"\"\n s3_bucket_name = \"\"\n\n is_multi_region_trail = true # CRITICAL: apply the trail to all regions\n\n event_selector {\n include_management_events = true # CRITICAL: log management events\n read_write_type = \"All\" # CRITICAL: log both read & write\n }\n}\n```" }, "Recommendation": { - "Text": "Enable CloudTrail logging management events in All Regions", - "Url": "https://docs.prowler.com/checks/aws/logging-policies/logging_14" + "Text": "Enable a **multi-region CloudTrail** that logs **management events** for `read` and `write` in all regions.\n\nCentralize logs in a separate, locked-down account; apply **least privilege**, encryption, retention, and integrity validation; and protect trails and storage with tamper-evident, deny-delete controls for **defense-in-depth**.", + "Url": "https://hub.prowler.com/check/cloudtrail_multi_region_enabled_logging_management_events" } }, "Categories": [ + "logging", "forensics-ready" ], "DependsOn": [], diff --git a/prowler/providers/aws/services/cloudtrail/cloudtrail_s3_dataevents_read_enabled/cloudtrail_s3_dataevents_read_enabled.metadata.json b/prowler/providers/aws/services/cloudtrail/cloudtrail_s3_dataevents_read_enabled/cloudtrail_s3_dataevents_read_enabled.metadata.json index 3e3f074c5f..31288482e7 100644 --- a/prowler/providers/aws/services/cloudtrail/cloudtrail_s3_dataevents_read_enabled/cloudtrail_s3_dataevents_read_enabled.metadata.json +++ b/prowler/providers/aws/services/cloudtrail/cloudtrail_s3_dataevents_read_enabled/cloudtrail_s3_dataevents_read_enabled.metadata.json @@ -1,31 +1,41 @@ { "Provider": "aws", "CheckID": "cloudtrail_s3_dataevents_read_enabled", - "CheckTitle": "Check if S3 buckets have Object-level logging for read events is enabled in CloudTrail.", + "CheckTitle": "CloudTrail trail records S3 object-level read events for all S3 buckets", "CheckType": [ - "Logging and Monitoring" + "Software and Configuration Checks/AWS Security Best Practices", + "Software and Configuration Checks/Industry and Regulatory Standards/AWS Foundational Security Best Practices" ], "ServiceName": "cloudtrail", "SubServiceName": "", - "ResourceIdTemplate": "arn:partition:service:region:account-id:resource-id", + "ResourceIdTemplate": "", "Severity": "low", "ResourceType": "AwsCloudTrailTrail", - "Description": "Ensure that all your AWS CloudTrail trails are configured to log Data events in order to record S3 object-level API operations, such as GetObject, DeleteObject and PutObject, for individual S3 buckets or for all current and future S3 buckets provisioned in your AWS account.", - "Risk": "If logs are not enabled, monitoring of service use and threat analysis is not possible.", + "Description": "**CloudTrail trails** log **S3 object-level read data events** for all buckets, capturing object access (for example `GetObject`) via selectors targeting `AWS::S3::Object`", + "Risk": "Without **object-level read logging**, S3 access is opaque. Attackers or insiders can exfiltrate data via `GetObject` without audit trails, eroding **confidentiality** and hindering **forensics**, anomaly detection, and incident response.", "RelatedUrl": "", + "AdditionalURLs": [ + "https://awswala.medium.com/enable-cloudtrail-data-events-logging-for-objects-in-an-s3-bucket-33cade51ae2b", + "https://docs.aws.amazon.com/securityhub/latest/userguide/s3-controls.html#s3-23", + "https://docs.aws.amazon.com/AmazonS3/latest/userguide/enable-cloudtrail-logging-for-s3.html", + "https://www.plerion.com/cloud-knowledge-base/ensure-object-level-logging-for-read-events-enabled-for-s3-bucket" + ], "Remediation": { "Code": { - "CLI": "aws cloudtrail put-event-selectors --trail-name --event-selectors '[{ 'ReadWriteType': 'ReadOnly', 'IncludeManagementEvents':true, 'DataResources': [{ 'Type': 'AWS::S3::Object', 'Values': ['arn:aws:s3'] }] }]'", - "NativeIaC": "", - "Other": "https://docs.aws.amazon.com/securityhub/latest/userguide/s3-controls.html#s3-23", - "Terraform": "" + "CLI": "aws cloudtrail put-event-selectors --trail-name --event-selectors '[{\"ReadWriteType\":\"ReadOnly\",\"DataResources\":[{\"Type\":\"AWS::S3::Object\",\"Values\":[\"arn:aws:s3\"]}]}]'", + "NativeIaC": "```yaml\n# CloudFormation: enable S3 object-level READ data events for all buckets on a trail\nResources:\n :\n Type: AWS::CloudTrail::Trail\n Properties:\n S3BucketName: \n EventSelectors:\n - ReadWriteType: ReadOnly # CRITICAL: log read-only data events\n DataResources:\n - Type: AWS::S3::Object # CRITICAL: target S3 object-level events\n Values:\n - arn:aws:s3 # CRITICAL: applies to all S3 buckets/objects\n```", + "Other": "1. In the AWS Console, open CloudTrail and select Trails\n2. Open your trail and go to the Data events section\n3. Add data event for S3 and choose All current and future S3 buckets\n4. Select only Read events (or All if Read-only is unavailable)\n5. Save changes", + "Terraform": "```hcl\n# Terraform: enable S3 object-level READ data events for all buckets on a trail\nresource \"aws_cloudtrail\" \"\" {\n name = \"\"\n s3_bucket_name = \"\"\n\n event_selector {\n read_write_type = \"ReadOnly\" # CRITICAL: log read-only data events\n data_resource {\n type = \"AWS::S3::Object\" # CRITICAL: target S3 object-level events\n values = [\"arn:aws:s3\"] # CRITICAL: apply to all S3 buckets/objects\n }\n }\n}\n```" }, "Recommendation": { - "Text": "Enable logs. Create an S3 lifecycle policy. Define use cases, metrics and automated responses where applicable.", - "Url": "https://docs.aws.amazon.com/AmazonS3/latest/userguide/enable-cloudtrail-logging-for-s3.html" + "Text": "Enable CloudTrail **data events** for S3 objects with `ReadOnly` (or `All`) across all current and future buckets. Use a multi-Region trail, centralize logs in an encrypted bucket with lifecycle retention, and integrate monitoring/alerts to support **defense in depth** and accountable access.", + "Url": "https://hub.prowler.com/check/cloudtrail_s3_dataevents_read_enabled" } }, - "Categories": [], + "Categories": [ + "logging", + "forensics-ready" + ], "DependsOn": [], "RelatedTo": [], "Notes": "" diff --git a/prowler/providers/aws/services/cloudtrail/cloudtrail_s3_dataevents_write_enabled/cloudtrail_s3_dataevents_write_enabled.metadata.json b/prowler/providers/aws/services/cloudtrail/cloudtrail_s3_dataevents_write_enabled/cloudtrail_s3_dataevents_write_enabled.metadata.json index 42c2801cc4..09772572a7 100644 --- a/prowler/providers/aws/services/cloudtrail/cloudtrail_s3_dataevents_write_enabled/cloudtrail_s3_dataevents_write_enabled.metadata.json +++ b/prowler/providers/aws/services/cloudtrail/cloudtrail_s3_dataevents_write_enabled/cloudtrail_s3_dataevents_write_enabled.metadata.json @@ -1,31 +1,41 @@ { "Provider": "aws", "CheckID": "cloudtrail_s3_dataevents_write_enabled", - "CheckTitle": "Check if S3 buckets have Object-level logging for write events is enabled in CloudTrail.", + "CheckTitle": "CloudTrail trail records all S3 object-level API operations for all buckets", "CheckType": [ - "Logging and Monitoring" + "Software and Configuration Checks/AWS Security Best Practices", + "Software and Configuration Checks/Industry and Regulatory Standards/AWS Foundational Security Best Practices", + "Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark" ], "ServiceName": "cloudtrail", "SubServiceName": "", - "ResourceIdTemplate": "arn:partition:service:region:account-id:resource-id", + "ResourceIdTemplate": "", "Severity": "low", "ResourceType": "AwsCloudTrailTrail", - "Description": "Ensure that all your AWS CloudTrail trails are configured to log Data events in order to record S3 object-level API operations, such as GetObject, DeleteObject and PutObject, for individual S3 buckets or for all current and future S3 buckets provisioned in your AWS account.", - "Risk": "If logs are not enabled, monitoring of service use and threat analysis is not possible.", + "Description": "**CloudTrail trails** include **S3 object-level data events** for **write (or all) operations** across **all current and future buckets**, via classic or advanced selectors. This records actions like `PutObject`, `DeleteObject`, and multipart uploads at the object level.", + "Risk": "Without object-level write logging, unauthorized or accidental changes and deletions can go unobserved, undermining data **integrity** and **availability**. Forensics lose visibility into who modified or removed objects, hindering detection of ransomware, rogue automation, or insider tampering.", "RelatedUrl": "", + "AdditionalURLs": [ + "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/logging-data-events-with-cloudtrail.html", + "https://docs.aws.amazon.com/AmazonS3/latest/userguide/enable-cloudtrail-logging-for-s3.html", + "https://www.go2share.net/article/s3-bucket-logging", + "https://docs.amazonaws.cn/en_us/AmazonS3/latest/userguide/cloudtrail-logging-s3-info.html", + "https://docs.aws.amazon.com/securityhub/latest/userguide/s3-controls.html#s3-22" + ], "Remediation": { "Code": { - "CLI": "aws cloudtrail put-event-selectors --trail-name --event-selectors '[{ 'ReadWriteType': 'WriteOnly', 'IncludeManagementEvents':true, 'DataResources': [{ 'Type': 'AWS::S3::Object', 'Values': ['arn:aws:s3'] }] }]'", - "NativeIaC": "", - "Other": "https://docs.aws.amazon.com/securityhub/latest/userguide/s3-controls.html#s3-22", - "Terraform": "" + "CLI": "aws cloudtrail put-event-selectors --trail-name --event-selectors '[{\"ReadWriteType\":\"WriteOnly\",\"DataResources\":[{\"Type\":\"AWS::S3::Object\",\"Values\":[\"arn:aws:s3\"]}]}]'", + "NativeIaC": "```yaml\nResources:\n :\n Type: AWS::CloudTrail::Trail\n Properties:\n TrailName: \n S3BucketName: \n EventSelectors:\n - ReadWriteType: WriteOnly\n DataResources:\n - Type: AWS::S3::Object\n Values:\n - arn:aws:s3 # Critical: enables S3 object-level write data events for all buckets, fixing the check\n```", + "Other": "1. In the AWS Console, open CloudTrail and go to Trails\n2. Select and click Edit under Data events\n3. For Data event source, choose S3\n4. Select All current and future S3 buckets\n5. Check Write events (or All events)\n6. Click Save changes", + "Terraform": "```hcl\nresource \"aws_cloudtrail\" \"\" {\n name = \"\"\n s3_bucket_name = \"\"\n\n event_selector {\n read_write_type = \"WriteOnly\"\n data_resource {\n type = \"AWS::S3::Object\"\n values = [\"arn:aws:s3\"] # Critical: logs S3 object-level write events for all buckets to pass the check\n }\n }\n}\n```" }, "Recommendation": { - "Text": "Enable logs. Create an S3 lifecycle policy. Define use cases, metrics and automated responses where applicable.", - "Url": "https://docs.aws.amazon.com/AmazonS3/latest/userguide/enable-cloudtrail-logging-for-s3.html" + "Text": "Enable **CloudTrail S3 data events** for object-level **write** (and *optionally* read) across all buckets on a multi-Region trail. Apply **least privilege** to log storage, set **lifecycle** retention, and integrate alerts. Use **advanced selectors** to target sensitive buckets/operations for cost control and **defense in depth**.", + "Url": "https://hub.prowler.com/check/cloudtrail_s3_dataevents_write_enabled" } }, "Categories": [ + "logging", "forensics-ready" ], "DependsOn": [], diff --git a/prowler/providers/aws/services/cloudtrail/cloudtrail_threat_detection_enumeration/cloudtrail_threat_detection_enumeration.metadata.json b/prowler/providers/aws/services/cloudtrail/cloudtrail_threat_detection_enumeration/cloudtrail_threat_detection_enumeration.metadata.json index d0b943254a..d41cda9430 100644 --- a/prowler/providers/aws/services/cloudtrail/cloudtrail_threat_detection_enumeration/cloudtrail_threat_detection_enumeration.metadata.json +++ b/prowler/providers/aws/services/cloudtrail/cloudtrail_threat_detection_enumeration/cloudtrail_threat_detection_enumeration.metadata.json @@ -1,26 +1,37 @@ { "Provider": "aws", "CheckID": "cloudtrail_threat_detection_enumeration", - "CheckTitle": "Ensure there are no potential enumeration threats in CloudTrail", - "CheckType": [], + "CheckTitle": "CloudTrail logs show no potential enumeration activity", + "CheckType": [ + "TTPs/Discovery", + "Software and Configuration Checks/AWS Security Best Practices/Runtime Behavior Analysis", + "Unusual Behaviors/User" + ], "ServiceName": "cloudtrail", "SubServiceName": "", - "ResourceIdTemplate": "arn:partition:service:region:account-id:resource-id", + "ResourceIdTemplate": "", "Severity": "critical", "ResourceType": "AwsCloudTrailTrail", - "Description": "This check ensures that there are no potential enumeration threats in CloudTrail.", - "Risk": "Potential enumeration threats in CloudTrail can lead to unauthorized access to resources.", + "Description": "**CloudTrail activity** is analyzed for AWS identities executing a broad mix of discovery APIs like `List*`, `Describe*`, and `Get*` within a recent time window.\n\nAn identity exceeding a configurable ratio of these actions indicates potential enumeration behavior by that principal.", + "Risk": "Concentrated discovery activity signals **reconnaissance** with valid credentials. Adversaries can map assets and policies to enable **privilege escalation**, target data stores for **exfiltration** (confidentiality), and identify services to disrupt (availability), supporting stealthy lateral movement.", "RelatedUrl": "", + "AdditionalURLs": [ + "https://medium.com/falconforce/falconfriday-detecting-enumeration-in-aws-0xff25-orangecon-25-edition-4aee83651088", + "https://www.elastic.co/guide/en/security/8.19/aws-discovery-api-calls-via-cli-from-a-single-resource.html", + "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-concepts.html#cloudtrail-concepts-logging-data-events", + "https://aws.plainenglish.io/aws-cloudtrail-event-cheatsheet-a-detection-engineers-guide-to-critical-api-calls-part-1-04fb1588556f", + "https://support.icompaas.com/support/solutions/articles/62000233455-ensure-there-are-no-potential-enumeration-threats-in-cloudtrail-" + ], "Remediation": { "Code": { - "CLI": "", - "NativeIaC": "", - "Other": "", - "Terraform": "" + "CLI": "aws iam update-access-key --user-name --access-key-id --status Inactive", + "NativeIaC": "```yaml\n# CloudFormation: deny common enumeration APIs for a specific IAM user\nResources:\n DenyEnumerationPolicy:\n Type: AWS::IAM::Policy\n Properties:\n PolicyName: deny-enumeration\n PolicyDocument:\n Version: \"2012-10-17\"\n Statement:\n - Effect: Deny # CRITICAL: blocks typical enumeration calls\n Action:\n - ec2:Describe* # CRITICAL: deny EC2 describe APIs\n - iam:List* # CRITICAL: deny IAM list APIs\n - s3:List* # CRITICAL: deny S3 list APIs\n - s3:Get* # CRITICAL: deny S3 get APIs (e.g., GetBucketAcl)\n Resource: \"*\"\n Users:\n - \"\" # CRITICAL: target the enumerating user\n```", + "Other": "1. In AWS Console, go to IAM > Users and open the user shown in the alert (ARN in the finding)\n2. Select the Security credentials tab\n3. For each active Access key, click Deactivate to set status to Inactive\n4. If the activity came from an EC2 instance role: go to EC2 > Instances > select the instance > Security > IAM role > Detach IAM role\n5. Re-run the check to confirm no new enumeration events occur", + "Terraform": "```hcl\n# Deny common enumeration APIs for a specific IAM user\nresource \"aws_iam_user_policy\" \"\" {\n name = \"deny-enumeration\"\n user = \"\"\n\n policy = jsonencode({\n Version = \"2012-10-17\",\n Statement = [{\n Effect = \"Deny\", # CRITICAL: blocks typical enumeration calls\n Action = [\n \"ec2:Describe*\", # CRITICAL\n \"iam:List*\", # CRITICAL\n \"s3:List*\", # CRITICAL\n \"s3:Get*\" # CRITICAL\n ],\n Resource = \"*\"\n }]\n })\n}\n```" }, "Recommendation": { - "Text": "To remediate this issue, ensure that there are no potential enumeration threats in CloudTrail.", - "Url": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-concepts.html#cloudtrail-concepts-logging-data-events" + "Text": "Apply **least privilege** to limit `List*`/`Describe*`/`Get*` to necessary resources and roles; use **separation of duties**.\n- Enforce MFA and short-lived sessions\n- Use **SCPs** to curb unnecessary discovery\n- Baseline expected reads and alert on spikes as **defense in depth**", + "Url": "https://hub.prowler.com/check/cloudtrail_threat_detection_enumeration" } }, "Categories": [ diff --git a/prowler/providers/aws/services/cloudtrail/cloudtrail_threat_detection_llm_jacking/cloudtrail_threat_detection_llm_jacking.metadata.json b/prowler/providers/aws/services/cloudtrail/cloudtrail_threat_detection_llm_jacking/cloudtrail_threat_detection_llm_jacking.metadata.json index 9b24373bcc..d961bc0764 100644 --- a/prowler/providers/aws/services/cloudtrail/cloudtrail_threat_detection_llm_jacking/cloudtrail_threat_detection_llm_jacking.metadata.json +++ b/prowler/providers/aws/services/cloudtrail/cloudtrail_threat_detection_llm_jacking/cloudtrail_threat_detection_llm_jacking.metadata.json @@ -1,30 +1,43 @@ { "Provider": "aws", "CheckID": "cloudtrail_threat_detection_llm_jacking", - "CheckTitle": "Ensure there are no potential LLM Jacking threats in CloudTrail.", - "CheckType": [], + "CheckTitle": "No potential LLM jacking activity detected in CloudTrail", + "CheckType": [ + "Software and Configuration Checks/AWS Security Best Practices/Runtime Behavior Analysis", + "TTPs/Discovery", + "TTPs/Execution", + "TTPs/Defense Evasion", + "Effects/Resource Consumption", + "Unusual Behaviors/User" + ], "ServiceName": "cloudtrail", "SubServiceName": "", - "ResourceIdTemplate": "arn:partition:service:region:account-id:resource-id", + "ResourceIdTemplate": "", "Severity": "critical", "ResourceType": "AwsCloudTrailTrail", - "Description": "This check ensures that there are no potential LLM Jacking threats in CloudTrail. LLM Jacking attacks involve unauthorized access to cloud-hosted large language model (LLM) services, such as AWS Bedrock, by exploiting exposed credentials or vulnerabilities. These attacks can lead to resource hijacking, unauthorized model invocations, and high operational costs for the victim organization.", - "Risk": "Potential LLM Jacking threats in CloudTrail can lead to unauthorized access to sensitive AI models, stolen credentials, resource hijacking, or running costly workloads. Attackers may use reverse proxies or malicious credentials to sell access to models, exfiltrate sensitive data, or disrupt business operations.", - "RelatedUrl": "https://sysdig.com/blog/llmjacking-stolen-cloud-credentials-used-in-new-ai-attack/", + "Description": "**CloudTrail Bedrock activity** is analyzed per identity for a high diversity of LLM-related API calls (e.g., `InvokeModel`, `InvokeModelWithResponseStream`, `GetFoundationModelAvailability`). *If an identity's share of these actions exceeds a configured threshold over a recent window*, it is surfaced as potential **LLM-jacking** behavior.", + "Risk": "Such patterns suggest **stolen credential** abuse to drive LLM usage.\n- Availability: cost exhaustion and service disruption\n- Confidentiality: leakage of prompts/outputs and model settings\n- Integrity: misuse of permissions for broader access\nAttackers may use reverse proxies to resell access and obfuscate sources.", + "RelatedUrl": "", + "AdditionalURLs": [ + "https://furkangungor.medium.com/automating-anomaly-detection-in-aws-cloudtrail-logs-4efb2ad9b958", + "https://help.sumologic.com/docs/integrations/amazon-aws/amazon-bedrock/", + "https://dzone.com/articles/ai-powered-aws-cloudtrail-analysis-strands-agent-bedrock" + ], "Remediation": { "Code": { "CLI": "", - "NativeIaC": "", - "Other": "", - "Terraform": "" + "NativeIaC": "```yaml\n# CloudFormation SCP that blocks all Amazon Bedrock actions to stop LLM jacking\nResources:\n :\n Type: AWS::Organizations::Policy\n Properties:\n Name: \n Type: SERVICE_CONTROL_POLICY\n TargetIds:\n - \"\" # CRITICAL: Attach SCP to the root/OU/account to enforce the deny\n Content:\n Version: \"2012-10-17\"\n Statement:\n - Sid: DenyBedrock\n Effect: Deny\n Action: \"bedrock:*\" # CRITICAL: Denies all Bedrock APIs (Invoke/Converse/list/entitlements/etc.)\n Resource: \"*\" # CRITICAL: Apply deny to all resources\n```", + "Other": "1. In the AWS Console, go to Organizations > Policies > Service control policies\n2. Click Create policy\n3. Set Name to \n4. In Policy, paste a deny for Bedrock:\n {\n \"Version\": \"2012-10-17\",\n \"Statement\": [{\"Sid\":\"DenyBedrock\",\"Effect\":\"Deny\",\"Action\":\"bedrock:*\",\"Resource\":\"*\"}]\n }\n5. Save the policy and click Attach\n6. Select the target (Root, OU, or the affected account ID ) and attach the policy\n7. Wait for propagation; no further Bedrock calls will occur, and the finding will clear after the detection window elapses", + "Terraform": "```hcl\n# SCP denying all Amazon Bedrock actions; attach it to the root/OU/account to halt LLM jacking\nresource \"aws_organizations_policy\" \"main\" {\n name = \"\"\n type = \"SERVICE_CONTROL_POLICY\"\n\n content = jsonencode({\n Version = \"2012-10-17\"\n Statement = [{\n Sid = \"DenyBedrock\"\n Effect = \"Deny\"\n Action = \"bedrock:*\" // CRITICAL: blocks all Bedrock APIs (prevents further suspicious activity)\n Resource = \"*\" // CRITICAL: deny across all resources\n }]\n })\n}\n\nresource \"aws_organizations_policy_attachment\" \"attach\" {\n policy_id = aws_organizations_policy.main.id\n target_id = \"\" // CRITICAL: attach to the affected account/OU/root to enforce the deny\n}\n```" }, "Recommendation": { - "Text": "To remediate this issue, enable detailed CloudTrail logging for Bedrock API calls, monitor suspicious activities, and secure sensitive credentials. Enable logging of model invocation inputs and outputs, and restrict access using IAM policies. Review CloudTrail logs regularly for suspicious `InvokeModel` actions or unauthorized access to models.", - "Url": "https://permiso.io/blog/exploiting-hosted-models" + "Text": "Apply **least privilege** to Bedrock; restrict `Invoke*` only to required roles and deny broadly via **SCPs** where unused. Enforce **MFA** and short-lived creds; rotate/remove exposed keys. Enable **model invocation logging** and budgets/quotas. Continuously monitor for Bedrock enumeration plus invoke bursts. Use **defense in depth** across identities and networks.", + "Url": "https://hub.prowler.com/check/cloudtrail_threat_detection_llm_jacking" } }, "Categories": [ - "threat-detection" + "threat-detection", + "gen-ai" ], "DependsOn": [], "RelatedTo": [], diff --git a/prowler/providers/aws/services/cloudtrail/cloudtrail_threat_detection_privilege_escalation/cloudtrail_threat_detection_privilege_escalation.metadata.json b/prowler/providers/aws/services/cloudtrail/cloudtrail_threat_detection_privilege_escalation/cloudtrail_threat_detection_privilege_escalation.metadata.json index f5237a1948..c725d4f1bd 100644 --- a/prowler/providers/aws/services/cloudtrail/cloudtrail_threat_detection_privilege_escalation/cloudtrail_threat_detection_privilege_escalation.metadata.json +++ b/prowler/providers/aws/services/cloudtrail/cloudtrail_threat_detection_privilege_escalation/cloudtrail_threat_detection_privilege_escalation.metadata.json @@ -1,26 +1,34 @@ { "Provider": "aws", "CheckID": "cloudtrail_threat_detection_privilege_escalation", - "CheckTitle": "Ensure there are no potential privilege escalation threats in CloudTrail", - "CheckType": [], + "CheckTitle": "No potential privilege escalation activity detected in CloudTrail", + "CheckType": [ + "TTPs/Privilege Escalation", + "Software and Configuration Checks/AWS Security Best Practices/Runtime Behavior Analysis" + ], "ServiceName": "cloudtrail", "SubServiceName": "", - "ResourceIdTemplate": "arn:partition:service:region:account-id:resource-id", + "ResourceIdTemplate": "", "Severity": "critical", "ResourceType": "AwsCloudTrailTrail", - "Description": "This check ensures that there are no potential privilege escalation threats in CloudTrail.", - "Risk": "Potential privilege escalation threats in CloudTrail can lead to unauthorized access to resources.", + "Description": "**CloudTrail** activity is analyzed for **identities** executing high-risk actions linked to **privilege escalation** (e.g., `Attach*Policy`, `PassRole`, `AssumeRole`, `CreateAccessKey`). Identities exceeding a configurable share of such events within a *recent time window* are highlighted for investigation.", + "Risk": "Escalation patterns can grant elevated entitlements, enabling:\n- Confidentiality loss via unauthorized data/secret access\n- Integrity compromise by changing IAM policies/roles\n- Availability impact by tampering with logging or resources\nThis also facilitates lateral movement and persistence.", "RelatedUrl": "", + "AdditionalURLs": [ + "https://rhinosecuritylabs.com/aws/aws-privilege-escalation-methods-mitigation/", + "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-concepts.html#cloudtrail-concepts-logging-data-events", + "https://signmycode.com/blog/what-is-privilege-escalation-in-aws-recommendations-to-prevent-it" + ], "Remediation": { "Code": { "CLI": "", - "NativeIaC": "", - "Other": "", - "Terraform": "" + "NativeIaC": "```yaml\n# CloudFormation: Organization SCP to block common IAM privilege-escalation actions\nResources:\n :\n Type: AWS::Organizations::Policy\n Properties:\n Name: deny-iam-privesc\n Type: SERVICE_CONTROL_POLICY\n # Critical: This SCP denies risky IAM actions often used for privilege escalation\n # Explanation: Denying these actions organization-wide prevents future privesc activity detected by CloudTrail\n Content: |\n {\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Effect\": \"Deny\",\n \"Action\": [\n \"iam:AttachUserPolicy\",\n \"iam:AttachRolePolicy\",\n \"iam:PutUserPolicy\",\n \"iam:PutRolePolicy\",\n \"iam:PutGroupPolicy\",\n \"iam:AddUserToGroup\",\n \"iam:CreateAccessKey\",\n \"iam:CreateLoginProfile\",\n \"iam:UpdateLoginProfile\",\n \"iam:UpdateAssumeRolePolicy\",\n \"iam:CreatePolicyVersion\",\n \"iam:SetDefaultPolicyVersion\",\n \"iam:PassRole\"\n ],\n \"Resource\": \"*\"\n }\n ]\n }\n Attachment:\n Type: AWS::Organizations::PolicyAttachment\n Properties:\n # Critical: Attach the SCP so it is enforced\n PolicyId: !Ref \n TargetId: # OU, Root, or Account ID\n```", + "Other": "1. In AWS Console, open IAM and identify the AWS identity shown in the Prowler finding (user or role ARN)\n2. If it is an IAM user:\n - Go to Security credentials > Access keys, set active keys to Inactive\n - Go to Permissions, detach all managed policies and delete inline policies\n - Go to Groups, remove the user from privileged groups\n - Go to Console password, delete the login profile\n3. If it is an IAM role:\n - Go to Permissions, detach managed policies and delete inline policies\n - Go to Trust relationships, remove principals that should not assume the role and save\n4. Re-run the scan after the detection window elapses to confirm no further privilege-escalation activity is detected", + "Terraform": "```hcl\n# SCP to block common IAM privilege-escalation actions\nresource \"aws_organizations_policy\" \"\" {\n name = \"deny-iam-privesc\"\n type = \"SERVICE_CONTROL_POLICY\"\n\n # Critical: Deny risky IAM actions to prevent future privesc\n # Explanation: Blocks escalation techniques commonly seen in CloudTrail\n content = jsonencode({\n Version = \"2012-10-17\",\n Statement = [\n {\n Effect = \"Deny\",\n Action = [\n \"iam:AttachUserPolicy\",\n \"iam:AttachRolePolicy\",\n \"iam:PutUserPolicy\",\n \"iam:PutRolePolicy\",\n \"iam:PutGroupPolicy\",\n \"iam:AddUserToGroup\",\n \"iam:CreateAccessKey\",\n \"iam:CreateLoginProfile\",\n \"iam:UpdateLoginProfile\",\n \"iam:UpdateAssumeRolePolicy\",\n \"iam:CreatePolicyVersion\",\n \"iam:SetDefaultPolicyVersion\",\n \"iam:PassRole\"\n ],\n Resource = \"*\"\n }\n ]\n })\n}\n\nresource \"aws_organizations_policy_attachment\" \"_attach\" {\n # Critical: Attach the SCP so it takes effect\n policy_id = aws_organizations_policy..id\n target_id = \"\" # OU, Root, or Account ID\n}\n```" }, "Recommendation": { - "Text": "To remediate this issue, ensure that there are no potential privilege escalation threats in CloudTrail.", - "Url": "https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-concepts.html#cloudtrail-concepts-logging-data-events" + "Text": "Apply **least privilege** and **defense in depth**:\n- Restrict `PassRole`, `Attach*Policy`, `UpdateAssumeRolePolicy`, `CreateAccessKey`\n- Enforce permission boundaries and SCPs\n- Require MFA and change approvals\n- Use multi-Region CloudTrail, immutable retention, and alerting on anomalous sequences", + "Url": "https://hub.prowler.com/check/cloudtrail_threat_detection_privilege_escalation" } }, "Categories": [ diff --git a/prowler/providers/aws/services/directoryservice/directoryservice_directory_log_forwarding_enabled/directoryservice_directory_log_forwarding_enabled.metadata.json b/prowler/providers/aws/services/directoryservice/directoryservice_directory_log_forwarding_enabled/directoryservice_directory_log_forwarding_enabled.metadata.json index 153e8d3600..02f7b89c45 100644 --- a/prowler/providers/aws/services/directoryservice/directoryservice_directory_log_forwarding_enabled/directoryservice_directory_log_forwarding_enabled.metadata.json +++ b/prowler/providers/aws/services/directoryservice/directoryservice_directory_log_forwarding_enabled/directoryservice_directory_log_forwarding_enabled.metadata.json @@ -1,26 +1,35 @@ { "Provider": "aws", "CheckID": "directoryservice_directory_log_forwarding_enabled", - "CheckTitle": "Directory Service monitoring with CloudWatch logs.", - "CheckType": [], + "CheckTitle": "Directory Service directory has log forwarding to CloudWatch Logs enabled", + "CheckType": [ + "Software and Configuration Checks/AWS Security Best Practices", + "Software and Configuration Checks/Industry and Regulatory Standards/AWS Foundational Security Best Practices" + ], "ServiceName": "directoryservice", "SubServiceName": "", - "ResourceIdTemplate": "arn:partition:codeartifact:region:account-id:directory/directory-id", + "ResourceIdTemplate": "", "Severity": "medium", "ResourceType": "Other", - "Description": "Directory Service monitoring with CloudWatch logs.", - "Risk": "As a best practice, monitor your organization to ensure that changes are logged. This helps you to ensure that any unexpected change can be investigated and unwanted changes can be rolled back.", - "RelatedUrl": "https://docs.aws.amazon.com/directoryservice/latest/admin-guide/incident-response.html", + "Description": "**AWS Directory Service directories** are configured to forward domain controller security event logs to **CloudWatch Logs** using log subscriptions.\n\nEvaluation identifies directories with or without this forwarding in place.", + "Risk": "Without forwarding, visibility into AD security events is lost, delaying detection of suspicious authentications, policy changes, or privilege grants. Attackers can escalate and persist unnoticed, risking unauthorized access (confidentiality) and identity/policy manipulation (integrity), while hampering forensics and response.", + "RelatedUrl": "", + "AdditionalURLs": [ + "https://docs.amazonaws.cn/en_us/directoryservice/latest/admin-guide/ms_ad_enable_log_forwarding.html", + "https://docs.aws.amazon.com/directoryservice/latest/admin-guide/incident-response.html", + "https://docs.aws.amazon.com/directoryservice/latest/admin-guide/ms_ad_enable_log_forwarding.html", + "https://support.icompaas.com/support/solutions/articles/62000233528--ensure-directory-service-monitoring-with-cloudwatch-logs" + ], "Remediation": { "Code": { "CLI": "", - "NativeIaC": "", - "Other": "", - "Terraform": "" + "NativeIaC": "```yaml\n# CloudFormation: enable Directory Service log forwarding to CloudWatch Logs\nResources:\n LogGroup:\n Type: AWS::Logs::LogGroup\n Properties:\n LogGroupName: /aws/directoryservice/\n\n LogsResourcePolicy:\n Type: AWS::Logs::ResourcePolicy\n Properties:\n PolicyName: DSLogSubscription\n PolicyDocument: |\n {\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Principal\":{\"Service\":\"ds.amazonaws.com\"},\"Action\":[\"logs:CreateLogStream\",\"logs:PutLogEvents\",\"logs:DescribeLogStreams\"],\"Resource\":\"arn:aws:logs:*:*:log-group:/aws/directoryservice/*\"}]}\n\n DirectoryLogSubscription:\n Type: AWS::DirectoryService::LogSubscription\n Properties:\n DirectoryId: # CRITICAL: target Directory Service ID to enable log forwarding\n LogGroupName: /aws/directoryservice/ # CRITICAL: CloudWatch Logs destination\n```", + "Other": "1. In the AWS Console, go to Directory Service > Directories and open your directory\n2. On the Directory details page, select the Networking & security tab\n3. In Log forwarding, click Enable\n4. Choose Create a new CloudWatch log group (or select an existing one)\n5. Click Enable to start forwarding logs", + "Terraform": "```hcl\n# Enable Directory Service log forwarding to CloudWatch Logs\nresource \"aws_cloudwatch_log_group\" \"ds\" {\n name = \"/aws/directoryservice/\"\n}\n\nresource \"aws_cloudwatch_log_resource_policy\" \"ds\" {\n policy_name = \"DSLogSubscription\"\n policy_document = jsonencode({\n Version = \"2012-10-17\",\n Statement = [{\n Effect = \"Allow\",\n Principal = { Service = \"ds.amazonaws.com\" },\n Action = [\"logs:CreateLogStream\", \"logs:PutLogEvents\", \"logs:DescribeLogStreams\"],\n Resource = \"arn:aws:logs:*:*:log-group:/aws/directoryservice/*\"\n }]\n })\n}\n\nresource \"aws_directory_service_log_subscription\" \"enable\" {\n directory_id = \"\" # CRITICAL: enables log forwarding for this directory\n log_group_name = aws_cloudwatch_log_group.ds.name # CRITICAL: CloudWatch Logs destination\n}\n```" }, "Recommendation": { - "Text": "It is recommended that that the export of logs is enabled.", - "Url": "https://docs.aws.amazon.com/directoryservice/latest/admin-guide/incident-response.html" + "Text": "Enable and maintain **log forwarding** to CloudWatch Logs.\n\n- Centralize logs in a protected group with strict access and retention\n- Apply least privilege for delivery roles and readers; prevent tampering (immutability)\n- Alert on high-risk events and aggregate across Regions/accounts for defense in depth", + "Url": "https://hub.prowler.com/check/directoryservice_directory_log_forwarding_enabled" } }, "Categories": [ diff --git a/prowler/providers/aws/services/directoryservice/directoryservice_directory_monitor_notifications/directoryservice_directory_monitor_notifications.metadata.json b/prowler/providers/aws/services/directoryservice/directoryservice_directory_monitor_notifications/directoryservice_directory_monitor_notifications.metadata.json index 55d1c393c0..beafbd81da 100644 --- a/prowler/providers/aws/services/directoryservice/directoryservice_directory_monitor_notifications/directoryservice_directory_monitor_notifications.metadata.json +++ b/prowler/providers/aws/services/directoryservice/directoryservice_directory_monitor_notifications/directoryservice_directory_monitor_notifications.metadata.json @@ -1,29 +1,37 @@ { "Provider": "aws", "CheckID": "directoryservice_directory_monitor_notifications", - "CheckTitle": "Directory Service has SNS Notifications enabled.", - "CheckType": [], + "CheckTitle": "Directory Service directory has SNS notifications enabled", + "CheckType": [ + "Software and Configuration Checks/AWS Security Best Practices" + ], "ServiceName": "directoryservice", "SubServiceName": "", - "ResourceIdTemplate": "arn:partition:codeartifact:region:account-id:directory/directory-id", + "ResourceIdTemplate": "", "Severity": "medium", "ResourceType": "Other", - "Description": "Directory Service has SNS Notifications enabled.", - "Risk": "As a best practice, monitor status of Directory Service. This helps to avoid late actions to fix Directory Service issues.", - "RelatedUrl": "https://docs.aws.amazon.com/directoryservice/latest/admin-guide/ms_ad_enable_notifications.html", + "Description": "**AWS Directory Service** directories are associated with **Amazon SNS topics** to send status change notifications (e.g., `Active` `Impaired`).\n\nThe evaluation looks for directories that have SNS event topics configured for monitoring alerts.", + "Risk": "Missing directory notifications reduces visibility into health changes, causing delayed response to `Impaired` states. This threatens availability of authentication, Kerberos/LDAP lookups, and domain joins; increases MTTR; and can enable silent replication or trust failures that impact integrity across dependent workloads.", + "RelatedUrl": "", + "AdditionalURLs": [ + "https://docs.aws.amazon.com/directoryservice/latest/admin-guide/ms_ad_enable_notifications.html", + "https://support.icompaas.com/support/solutions/articles/62000233533-ensure-directory-service-has-sns-notifications-enabled" + ], "Remediation": { "Code": { - "CLI": "", + "CLI": "aws ds register-event-topic --directory-id --topic-name ", "NativeIaC": "", - "Other": "", + "Other": "1. Open AWS Console > Directory Service > Directories and select your directory\n2. Go to the Maintenance or Monitoring/Notifications section\n3. Click Actions > Create notification (or Set up notifications)\n4. Select an existing SNS topic (or create one) and Save", "Terraform": "" }, "Recommendation": { - "Text": "It is recommended set up SNS messaging to send email or text messages when the status of your directory changes.", - "Url": "https://docs.aws.amazon.com/directoryservice/latest/admin-guide/ms_ad_enable_notifications.html" + "Text": "Configure **AWS Directory Service** to publish directory status changes to an **SNS topic**, and subscribe your operations channels for timely alerts.\n\nApply **least privilege** on topic permissions, integrate alerts with incident response, and use **defense in depth** by pairing notifications with logs and dashboards.", + "Url": "https://hub.prowler.com/check/directoryservice_directory_monitor_notifications" } }, - "Categories": [], + "Categories": [ + "logging" + ], "DependsOn": [], "RelatedTo": [], "Notes": "" diff --git a/prowler/providers/aws/services/directoryservice/directoryservice_directory_snapshots_limit/directoryservice_directory_snapshots_limit.metadata.json b/prowler/providers/aws/services/directoryservice/directoryservice_directory_snapshots_limit/directoryservice_directory_snapshots_limit.metadata.json index 7693461252..85d6057f14 100644 --- a/prowler/providers/aws/services/directoryservice/directoryservice_directory_snapshots_limit/directoryservice_directory_snapshots_limit.metadata.json +++ b/prowler/providers/aws/services/directoryservice/directoryservice_directory_snapshots_limit/directoryservice_directory_snapshots_limit.metadata.json @@ -1,29 +1,38 @@ { "Provider": "aws", "CheckID": "directoryservice_directory_snapshots_limit", - "CheckTitle": "Directory Service Manual Snapshots limit reached.", - "CheckType": [], + "CheckTitle": "Directory Service directory has adequate remaining manual snapshot quota", + "CheckType": [ + "Software and Configuration Checks/AWS Security Best Practices", + "Effects/Resource Consumption" + ], "ServiceName": "directoryservice", "SubServiceName": "", - "ResourceIdTemplate": "arn:partition:codeartifact:region:account-id:directory/directory-id", + "ResourceIdTemplate": "", "Severity": "low", "ResourceType": "Other", - "Description": "Directory Service Manual Snapshots limit reached.", - "Risk": "A limit reached can bring unwanted results. The maximum number of manual snapshots is a hard limit.", - "RelatedUrl": "https://docs.aws.amazon.com/general/latest/gr/ds_region.html", + "Description": "**AWS Directory Service** directories with **manual snapshot capacity** fully consumed or nearly exhausted, based on current snapshot count relative to the directory's maximum allowed.", + "Risk": "With no remaining snapshot capacity, you cannot create new recovery points:\n- Reduced availability during outages or ransomware\n- Higher RPO from failed scheduled backups\n- Greater change risk (schema/OS updates) without a safe rollback", + "RelatedUrl": "", + "AdditionalURLs": [ + "https://support.icompaas.com/support/solutions/articles/62000233531--ensure-directory-service-manual-snapshots-limit-reached", + "https://docs.aws.amazon.com/directoryservice/latest/admin-guide/ms_ad_limits.html" + ], "Remediation": { "Code": { "CLI": "", "NativeIaC": "", - "Other": "", + "Other": "1. In the AWS Console, go to Directory Service > Directories and open \n2. Click Snapshots\n3. Select older snapshots with Type = Manual and click Delete snapshot, confirm\n4. Repeat until the number of manual snapshots is less than (manual limit - 2). For the default limit of 5, keep at most 2 manual snapshots\n5. Verify Remaining manual snapshots > 2 on the Snapshots page", "Terraform": "" }, "Recommendation": { - "Text": "Monitor manual snapshots limit to ensure capacity when you need it.", - "Url": "https://docs.aws.amazon.com/general/latest/gr/ds_region.html" + "Text": "Adopt a **snapshot lifecycle policy**: rotate/expire old manual snapshots after verifying restores, and alert on low headroom. Prefer **automated backups** for cadence and retention. Enforce **least privilege** for snapshot creation. Design operations within the *hard per-directory cap* to prevent capacity exhaustion.", + "Url": "https://hub.prowler.com/check/directoryservice_directory_snapshots_limit" } }, - "Categories": [], + "Categories": [ + "resilience" + ], "DependsOn": [], "RelatedTo": [], "Notes": "" diff --git a/prowler/providers/aws/services/directoryservice/directoryservice_ldap_certificate_expiration/directoryservice_ldap_certificate_expiration.metadata.json b/prowler/providers/aws/services/directoryservice/directoryservice_ldap_certificate_expiration/directoryservice_ldap_certificate_expiration.metadata.json index 982ab9091f..7e8510d0f3 100644 --- a/prowler/providers/aws/services/directoryservice/directoryservice_ldap_certificate_expiration/directoryservice_ldap_certificate_expiration.metadata.json +++ b/prowler/providers/aws/services/directoryservice/directoryservice_ldap_certificate_expiration/directoryservice_ldap_certificate_expiration.metadata.json @@ -1,29 +1,38 @@ { "Provider": "aws", "CheckID": "directoryservice_ldap_certificate_expiration", - "CheckTitle": "Directory Service LDAP Certificates expiration.", - "CheckType": [], + "CheckTitle": "Directory Service LDAP certificate expires in more than 90 days", + "CheckType": [ + "Software and Configuration Checks/AWS Security Best Practices", + "Software and Configuration Checks/Industry and Regulatory Standards/AWS Foundational Security Best Practices" + ], "ServiceName": "directoryservice", "SubServiceName": "", - "ResourceIdTemplate": "arn:partition:codeartifact:region:account-id:directory/directory-id", + "ResourceIdTemplate": "", "Severity": "medium", "ResourceType": "Other", - "Description": "Directory Service Manual Snapshots limit reached.", - "Risk": "Expired certificates can impact service availability.", - "RelatedUrl": "https://docs.aws.amazon.com/directoryservice/latest/admin-guide/ms_ad_ldap.html", + "Description": "**AWS Directory Service** Secure LDAP (LDAPS) certificates are assessed for upcoming expiration by comparing each directory's certificate expiration to the current time and identifying those with `<= 90` days remaining.", + "Risk": "Expired LDAPS certificates cause TLS handshakes to fail, blocking directory binds and queries and disrupting authentication and app integrations (availability). If clients fall back to plain LDAP, credentials and directory data can be intercepted or altered (confidentiality and integrity).", + "RelatedUrl": "", + "AdditionalURLs": [ + "https://docs.aws.amazon.com/directoryservice/latest/admin-guide/ms_ad_ldap.html", + "https://support.icompaas.com/support/solutions/articles/62000229587-ensure-to-monitor-directory-service-ldap-certificates-expiration" + ], "Remediation": { "Code": { - "CLI": "", + "CLI": "aws ds register-certificate --directory-id --certificate-data file://certificate.pem", "NativeIaC": "", - "Other": "", + "Other": "1. In the AWS Console, open Directory Service and select your AWS Managed Microsoft AD ()\n2. Go to Networking & security > Secure LDAP\n3. Click Edit (Manage certificate)\n4. Choose Replace certificate (or Upload certificate)\n5. Upload a new LDAPS server certificate with private key from a trusted CA (valid for >90 days); enter the password if using a .pfx\n6. Save and wait until the certificate status is Active", "Terraform": "" }, "Recommendation": { - "Text": "Monitor certificate expiration and take automated action to alarm responsible team for taking care of the replacement or remove.", - "Url": "https://docs.aws.amazon.com/directoryservice/latest/admin-guide/ms_ad_ldap.html" + "Text": "Adopt certificate lifecycle management: inventory LDAPS certificates, alert well before expiry, and automate renewal with staged rollout and overlap. Enforce TLS-only LDAP and disable plaintext fallback. Apply **least privilege** and **separation of duties** to certificate issuance and deployment.", + "Url": "https://hub.prowler.com/check/directoryservice_ldap_certificate_expiration" } }, - "Categories": [], + "Categories": [ + "encryption" + ], "DependsOn": [], "RelatedTo": [], "Notes": "" diff --git a/prowler/providers/aws/services/directoryservice/directoryservice_radius_server_security_protocol/directoryservice_radius_server_security_protocol.metadata.json b/prowler/providers/aws/services/directoryservice/directoryservice_radius_server_security_protocol/directoryservice_radius_server_security_protocol.metadata.json index a3f04834e3..60ffbc26da 100644 --- a/prowler/providers/aws/services/directoryservice/directoryservice_radius_server_security_protocol/directoryservice_radius_server_security_protocol.metadata.json +++ b/prowler/providers/aws/services/directoryservice/directoryservice_radius_server_security_protocol/directoryservice_radius_server_security_protocol.metadata.json @@ -1,29 +1,40 @@ { "Provider": "aws", "CheckID": "directoryservice_radius_server_security_protocol", - "CheckTitle": "Ensure Radius server in DS is using the recommended security protocol.", - "CheckType": [], + "CheckTitle": "Directory Service directory RADIUS server uses MS-CHAPv2", + "CheckType": [ + "Software and Configuration Checks/AWS Security Best Practices", + "Software and Configuration Checks/Industry and Regulatory Standards/AWS Foundational Security Best Practices", + "TTPs/Credential Access" + ], "ServiceName": "directoryservice", "SubServiceName": "", - "ResourceIdTemplate": "arn:partition:codeartifact:region:account-id:directory/directory-id", + "ResourceIdTemplate": "", "Severity": "medium", "ResourceType": "Other", - "Description": "Ensure Radius server in DS is using the recommended security protocol.", - "Risk": "As a best practice, you might need to configure the authentication protocol between the Microsoft AD DCs and the RADIUS/MFA server. Supported protocols are PAP, CHAP MS-CHAPv1, and MS-CHAPv2. MS-CHAPv2 is recommended because it provides the strongest security of the three options.", - "RelatedUrl": "https://aws.amazon.com/blogs/security/how-to-enable-multi-factor-authentication-for-amazon-workspaces-and-amazon-quicksight-by-using-microsoft-ad-and-on-premises-credentials/", + "Description": "AWS Directory Service RADIUS configuration uses the **authentication protocol** defined for MFA integration. The finding evaluates whether directories with RADIUS enabled are set to `MS-CHAPv2` instead of weaker options like `PAP`, `CHAP`, or `MS-CHAPv1`.", + "Risk": "Using `PAP`, `CHAP`, or `MS-CHAPv1` weakens RADIUS-based MFA.\n\n`PAP` exposes cleartext credentials, while legacy CHAP variants permit offline cracking and replay, enabling unauthorized access to AD-integrated services and lateral movement, degrading confidentiality and integrity.", + "RelatedUrl": "", + "AdditionalURLs": [ + "https://docs.secureauth.com/0903/en/ms-chapv2-and-radius--sp-initiated--for-cisco-and-netscaler-configuration-guide.html", + "https://docs.aws.amazon.com/directoryservice/latest/admin-guide/ms_ad_mfa.html", + "https://www.freeradius.org/documentation/freeradius-server/4.0~alpha1/raddb/mods-available/mschap.html" + ], "Remediation": { "Code": { - "CLI": "", + "CLI": "aws ds update-radius --directory-id --radius-settings AuthenticationProtocol=MS-CHAPv2", "NativeIaC": "", - "Other": "", - "Terraform": "" + "Other": "1. In the AWS Console, open Directory Service and select your directory\n2. Open the Networking & security tab (Multi-factor authentication section)\n3. Click Actions > Edit (or Enable)\n4. Set Protocol to MS-CHAPv2\n5. Click Save (or Enable) to apply", + "Terraform": "```hcl\nresource \"aws_directory_service_radius_settings\" \"\" {\n directory_id = \"\"\n radius_servers = [\"\"]\n shared_secret = \"\"\n\n authentication_protocol = \"MS-CHAPv2\" # Critical: sets the RADIUS auth protocol to MS-CHAPv2 to pass the check\n}\n```" }, "Recommendation": { - "Text": "MS-CHAPv2 provides the strongest security of the options supported, and is therefore recommended.", - "Url": "https://aws.amazon.com/blogs/security/how-to-enable-multi-factor-authentication-for-amazon-workspaces-and-amazon-quicksight-by-using-microsoft-ad-and-on-premises-credentials/" + "Text": "Standardize on `MS-CHAPv2` for RADIUS authentication to MFA providers. Disable `PAP`, `CHAP`, and `MS-CHAPv1` to prevent downgrades. Apply least privilege and defense in depth: use strong shared secrets, restrict network access to RADIUS endpoints, and monitor authentication logs for anomalies.", + "Url": "https://hub.prowler.com/check/directoryservice_radius_server_security_protocol" } }, - "Categories": [], + "Categories": [ + "identity-access" + ], "DependsOn": [], "RelatedTo": [], "Notes": "" diff --git a/prowler/providers/aws/services/directoryservice/directoryservice_supported_mfa_radius_enabled/directoryservice_supported_mfa_radius_enabled.metadata.json b/prowler/providers/aws/services/directoryservice/directoryservice_supported_mfa_radius_enabled/directoryservice_supported_mfa_radius_enabled.metadata.json index a5db8db7ad..35716021fd 100644 --- a/prowler/providers/aws/services/directoryservice/directoryservice_supported_mfa_radius_enabled/directoryservice_supported_mfa_radius_enabled.metadata.json +++ b/prowler/providers/aws/services/directoryservice/directoryservice_supported_mfa_radius_enabled/directoryservice_supported_mfa_radius_enabled.metadata.json @@ -1,29 +1,40 @@ { "Provider": "aws", "CheckID": "directoryservice_supported_mfa_radius_enabled", - "CheckTitle": "Ensure Multi-Factor Authentication (MFA) using Radius Server is enabled in DS.", - "CheckType": [], + "CheckTitle": "AWS Directory Service directory has RADIUS-based MFA enabled", + "CheckType": [ + "Software and Configuration Checks/AWS Security Best Practices", + "Industry and Regulatory Standards/AWS Foundational Security Best Practices", + "TTPs/Initial Access", + "TTPs/Credential Access" + ], "ServiceName": "directoryservice", "SubServiceName": "", - "ResourceIdTemplate": "arn:partition:codeartifact:region:account-id:directory/directory-id", + "ResourceIdTemplate": "", "Severity": "medium", "ResourceType": "Other", - "Description": "Ensure Multi-Factor Authentication (MFA) using Radius Server is enabled in DS.", - "Risk": "Multi-Factor Authentication (MFA) adds an extra layer of authentication assurance beyond traditional username and password.", - "RelatedUrl": "https://docs.aws.amazon.com/directoryservice/latest/admin-guide/ms_ad_mfa.html", + "Description": "**AWS Directory Service directories** are evaluated for **RADIUS-backed multi-factor authentication**, confirming that MFA is configured and the RADIUS integration is active.", + "Risk": "Without **RADIUS MFA**, directory-based sign-ins to AWS-integrated services rely on a single factor, enabling credential stuffing and phishing to succeed. Compromised passwords can grant unauthorized access, drive data exfiltration, and enable privilege escalation, undermining confidentiality and integrity.", + "RelatedUrl": "", + "AdditionalURLs": [ + "https://docs.aws.amazon.com/directoryservice/latest/admin-guide/ms_ad_mfa.html", + "https://support.icompaas.com/support/solutions/articles/62000233537-ensure-multi-factor-authentication-mfa-using-a-radius-server-is-enabled-in-directory-service" + ], "Remediation": { "Code": { - "CLI": "", + "CLI": "aws ds enable-radius --directory-id --radius-settings '{\"RadiusServers\":[\"\"],\"SharedSecret\":\"\"}'", "NativeIaC": "", - "Other": "", - "Terraform": "" + "Other": "1. Sign in to the AWS Console and open Directory Service\n2. Select your directory and open it\n3. Go to the Networking & security tab\n4. In Multi-factor authentication, click Actions > Enable\n5. Enter RADIUS server IP(s) and the Shared secret, then click Enable\n6. Wait until the RADIUS status shows Completed", + "Terraform": "```hcl\nresource \"aws_directory_service_radius_settings\" \"\" {\n directory_id = \"\" # Directory to enable RADIUS MFA on\n radius_servers = [\"\"] # Critical: RADIUS server endpoint(s)\n shared_secret = \"\" # Critical: Shared secret for RADIUS\n}\n```" }, "Recommendation": { - "Text": "Enabling MFA provides increased security to a user name and password as it requires the user to possess a solution that displays a time-sensitive authentication code.", - "Url": "https://docs.aws.amazon.com/directoryservice/latest/admin-guide/ms_ad_mfa.html" + "Text": "Enable and enforce **RADIUS-based MFA** for all Directory Service authentications. Apply **least privilege**, harden and monitor the RADIUS infrastructure, rotate shared secrets, and restrict network access (e.g., `UDP/1812`). Use **defense in depth** with segmentation and session controls to limit lateral movement and reduce blast radius.", + "Url": "https://hub.prowler.com/check/directoryservice_supported_mfa_radius_enabled" } }, - "Categories": [], + "Categories": [ + "identity-access" + ], "DependsOn": [], "RelatedTo": [], "Notes": "" diff --git a/prowler/providers/aws/services/dlm/dlm_ebs_snapshot_lifecycle_policy_exists/dlm_ebs_snapshot_lifecycle_policy_exists.metadata.json b/prowler/providers/aws/services/dlm/dlm_ebs_snapshot_lifecycle_policy_exists/dlm_ebs_snapshot_lifecycle_policy_exists.metadata.json index 12b55d3f12..db011dacd4 100644 --- a/prowler/providers/aws/services/dlm/dlm_ebs_snapshot_lifecycle_policy_exists/dlm_ebs_snapshot_lifecycle_policy_exists.metadata.json +++ b/prowler/providers/aws/services/dlm/dlm_ebs_snapshot_lifecycle_policy_exists/dlm_ebs_snapshot_lifecycle_policy_exists.metadata.json @@ -1,28 +1,34 @@ { "Provider": "aws", "CheckID": "dlm_ebs_snapshot_lifecycle_policy_exists", - "CheckTitle": "Ensure EBS Snapshot lifecycle policies are defined.", + "CheckTitle": "Region with EBS snapshots has at least one EBS snapshot lifecycle policy defined", "CheckType": [ - "Data Protection" + "Software and Configuration Checks/AWS Security Best Practices", + "Software and Configuration Checks/Industry and Regulatory Standards/AWS Foundational Security Best Practices" ], "ServiceName": "dlm", - "SubServiceName": "ebs", - "ResourceIdTemplate": "arn:aws:iam::account-id:resource-id", + "SubServiceName": "", + "ResourceIdTemplate": "", "Severity": "medium", "ResourceType": "Other", - "Description": "Ensure EBS Snapshot lifecycle policies are defined.", - "Risk": "With AWS DLM service, you can manage the lifecycle of your EBS volume snapshots. By automating the EBS volume backup management using lifecycle policies, you can protect your EBS data by enforcing a regular backup schedule, retain backups as required by auditors or internal compliance.", - "RelatedUrl": "https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/snapshot-lifecycle.html#dlm-elements", + "Description": "**EBS snapshots** are expected to be governed by **Data Lifecycle Manager (DLM) policies** in each Region where snapshots exist.\n\nThe evaluation looks for lifecycle policies that automate snapshot creation, retention, and cleanup for those snapshots.", + "Risk": "Without **automated lifecycle policies**, backups become inconsistent and error-prone, reducing availability and weakening recovery objectives. Missing retention rules cause premature deletion or snapshot sprawl, increasing cost and exposing stale data. Lack of cross-Region/account copies limits resilience to regional outages and malicious deletion.", + "RelatedUrl": "", + "AdditionalURLs": [ + "https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/DLM/ebs-snapshot-automation.html", + "https://repost.aws/articles/ARmYgZmA8MRQi89pWd9D7eFw/how-to-create-a-automate-backup-aws-data-lifecycle-management-using-snapshots", + "https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/snapshot-lifecycle.html#dlm-elements" + ], "Remediation": { "Code": { - "CLI": "aws dlm create-lifecycle-policy --region --execution-role-arn --description --state ENABLED --policy-details file://lifecycle-policy-config.json", - "NativeIaC": "", - "Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/DLM/ebs-snapshot-automation.html", - "Terraform": "" + "CLI": "aws dlm create-lifecycle-policy --region --execution-role-arn --description \"\" --state ENABLED --policy-details '{\"PolicyType\":\"EBS_SNAPSHOT_MANAGEMENT\",\"ResourceTypes\":[\"VOLUME\"],\"TargetTags\":[{\"Key\":\"\",\"Value\":\"\"}],\"Schedules\":[{\"CreateRule\":{\"Interval\":24,\"IntervalUnit\":\"HOURS\"},\"RetainRule\":{\"Count\":1}}]}'", + "NativeIaC": "```yaml\n# CloudFormation: minimal EBS snapshot lifecycle policy\nResources:\n :\n Type: AWS::DLM::LifecyclePolicy\n Properties:\n Description: \"\"\n ExecutionRoleArn: \"\"\n State: ENABLED # Critical: enables the policy so it is counted by the check\n PolicyDetails:\n PolicyType: EBS_SNAPSHOT_MANAGEMENT # Critical: creates an EBS snapshot lifecycle policy\n ResourceTypes: [VOLUME]\n TargetTags:\n - Key: \"\" # Critical: selects target volumes by tag\n Value: \"\"\n Schedules:\n - CreateRule:\n Interval: 24\n IntervalUnit: HOURS\n RetainRule:\n Count: 1\n```", + "Other": "1. In the AWS console, switch to the Region that has EBS snapshots\n2. Open EC2 > Lifecycle Manager (DLM) > Create lifecycle policy\n3. Select EBS snapshot policy; Target resource: Volumes\n4. Add Target tags: Key = , Value = \n5. Set Schedule: Create every 24 hours; Retain 1 snapshot\n6. Ensure State is Enabled and click Create policy", + "Terraform": "```hcl\n# Terraform: minimal EBS snapshot lifecycle policy\nresource \"aws_dlm_lifecycle_policy\" \"\" {\n description = \"\"\n execution_role_arn = \"\"\n state = \"ENABLED\" # Critical: enables the policy so it is counted by the check\n\n policy_details {\n policy_type = \"EBS_SNAPSHOT_MANAGEMENT\" # Critical: creates an EBS snapshot lifecycle policy\n resource_types = [\"VOLUME\"]\n target_tags = {\n \"\" = \"\" # Critical: selects target volumes by tag\n }\n schedule {\n create_rule {\n interval = 24\n interval_unit = \"HOURS\"\n }\n retain_rule {\n count = 1\n }\n }\n }\n}\n```" }, "Recommendation": { - "Text": "To use Amazon Data Lifecycle Manager (DLM) service to manage the lifecycle of your EBS volume snapshots, you have to tag your AWS EBS volumes and create data lifecycle policies via Amazon DLM.", - "Url": "https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/snapshot-lifecycle.html#dlm-elements" + "Text": "Implement **DLM lifecycle policies** for all volumes that require backup.\n\n- Schedule creations to meet RPO/RTO\n- Define retention to prevent sprawl and enforce least data exposure\n- Use **least privilege** roles and separation of duties\n- Copy snapshots to another Region/account for **defense in depth**\n- Monitor policy health and coverage with tags", + "Url": "https://hub.prowler.com/check/dlm_ebs_snapshot_lifecycle_policy_exists" } }, "Categories": [ diff --git a/prowler/providers/aws/services/dms/dms_endpoint_mongodb_authentication_enabled/dms_endpoint_mongodb_authentication_enabled.metadata.json b/prowler/providers/aws/services/dms/dms_endpoint_mongodb_authentication_enabled/dms_endpoint_mongodb_authentication_enabled.metadata.json index 8a0b800295..d8a57d00b5 100644 --- a/prowler/providers/aws/services/dms/dms_endpoint_mongodb_authentication_enabled/dms_endpoint_mongodb_authentication_enabled.metadata.json +++ b/prowler/providers/aws/services/dms/dms_endpoint_mongodb_authentication_enabled/dms_endpoint_mongodb_authentication_enabled.metadata.json @@ -1,31 +1,38 @@ { "Provider": "aws", "CheckID": "dms_endpoint_mongodb_authentication_enabled", - "CheckTitle": "Check if DMS endpoints for MongoDB have an authentication mechanism enabled.", + "CheckTitle": "DMS MongoDB endpoint has an authentication mechanism enabled", "CheckType": [ - "Software and Configuration Checks/AWS Security Best Practices" + "Software and Configuration Checks/AWS Security Best Practices", + "Effects/Data Exposure" ], "ServiceName": "dms", "SubServiceName": "", - "ResourceIdTemplate": "arn:aws:dms:region:account-id:endpoint/endpoint-id", + "ResourceIdTemplate": "", "Severity": "medium", "ResourceType": "AwsDmsEndpoint", - "Description": "This control checks whether an AWS DMS endpoint for MongoDB is configured with an authentication mechanism. The control fails if an authentication type isn't set for the endpoint.", - "Risk": "Without an authentication mechanism enabled, unauthorized users may gain access to sensitive data during migration, increasing the risk of data breaches and security incidents.", - "RelatedUrl": "https://docs.aws.amazon.com/dms/latest/userguide/CHAP_Source.MongoDB.html", + "Description": "**AWS DMS MongoDB endpoints** use an authentication mechanism. Configuration expects `AuthType` not `no` (e.g., `password`) with an `authMechanism` such as `scram_sha_1` or `mongodb_cr`.", + "Risk": "Without authentication, unauthenticated connections can access the source, degrading **confidentiality** and **integrity**. Adversaries could read or modify migrated documents, hijack CDC, inject data, or exfiltrate records during replication.", + "RelatedUrl": "", + "AdditionalURLs": [ + "https://docs.aws.amazon.com/dms/latest/userguide/CHAP_Source.MongoDB.html", + "https://docs.aws.amazon.com/securityhub/latest/userguide/dms-controls.html#dms-11" + ], "Remediation": { "Code": { - "CLI": "aws dms modify-endpoint --endpoint-arn --username --password --authentication-type ", - "NativeIaC": "", - "Other": "https://docs.aws.amazon.com/securityhub/latest/userguide/dms-controls.html#dms-11", - "Terraform": "" + "CLI": "aws dms modify-endpoint --endpoint-arn --mongodb-settings '{\"AuthType\":\"password\"}' --username --password ", + "NativeIaC": "```yaml\n# CloudFormation: enable authentication on a MongoDB DMS endpoint\nResources:\n :\n Type: AWS::DMS::Endpoint\n Properties:\n EndpointIdentifier: \n EndpointType: source\n EngineName: mongodb\n MongoDbSettings:\n AuthType: password # CRITICAL: sets authentication mode to 'password' so auth is enabled\n```", + "Other": "1. In the AWS Console, go to Database Migration Service > Endpoints\n2. Select the MongoDB endpoint and click Modify\n3. Under MongoDB settings, set Authentication mode to Password\n4. Enter Username and Password\n5. Click Save changes", + "Terraform": "```hcl\n# Terraform: enable authentication on a MongoDB DMS endpoint\nresource \"aws_dms_endpoint\" \"\" {\n endpoint_id = \"\"\n endpoint_type = \"source\"\n engine_name = \"mongodb\"\n\n mongodb_settings {\n auth_type = \"password\" # CRITICAL: enables authentication for the MongoDB endpoint\n }\n}\n```" }, "Recommendation": { - "Text": "Enable an authentication mechanism on DMS endpoints for MongoDB to ensure secure access control during migration.", - "Url": "https://docs.aws.amazon.com/dms/latest/userguide/CHAP_Source.MongoDB.html" + "Text": "Enforce **strong authentication** on MongoDB endpoints: set `AuthType` to `password` and use `authMechanism` like `scram_sha_1`. Apply **least privilege** database accounts, store secrets in **Secrets Manager**, and pair with **TLS** for defense in depth.", + "Url": "https://hub.prowler.com/check/dms_endpoint_mongodb_authentication_enabled" } }, - "Categories": [], + "Categories": [ + "identity-access" + ], "DependsOn": [], "RelatedTo": [], "Notes": "" diff --git a/prowler/providers/aws/services/dms/dms_endpoint_neptune_iam_authorization_enabled/dms_endpoint_neptune_iam_authorization_enabled.metadata.json b/prowler/providers/aws/services/dms/dms_endpoint_neptune_iam_authorization_enabled/dms_endpoint_neptune_iam_authorization_enabled.metadata.json index 45471a9268..ef8bfd6bde 100644 --- a/prowler/providers/aws/services/dms/dms_endpoint_neptune_iam_authorization_enabled/dms_endpoint_neptune_iam_authorization_enabled.metadata.json +++ b/prowler/providers/aws/services/dms/dms_endpoint_neptune_iam_authorization_enabled/dms_endpoint_neptune_iam_authorization_enabled.metadata.json @@ -1,31 +1,38 @@ { "Provider": "aws", "CheckID": "dms_endpoint_neptune_iam_authorization_enabled", - "CheckTitle": "Check if DMS endpoints for Neptune databases have IAM authorization enabled.", + "CheckTitle": "DMS endpoint for Neptune has IAM authorization enabled", "CheckType": [ - "Software and Configuration Checks/AWS Security Best Practices" + "Software and Configuration Checks/AWS Security Best Practices", + "Effects/Data Exposure" ], "ServiceName": "dms", "SubServiceName": "", - "ResourceIdTemplate": "arn:aws:dms:region:account-id:endpoint/endpoint-id", + "ResourceIdTemplate": "", "Severity": "medium", "ResourceType": "AwsDmsEndpoint", - "Description": "This control checks whether an AWS DMS endpoint for an Amazon Neptune database is configured with IAM authorization. The control fails if the DMS endpoint doesn't have IAM authorization enabled.", - "Risk": "Without IAM authorization, DMS endpoints for Neptune databases may lack granular access control, increasing the risk of unauthorized access to sensitive data.", - "RelatedUrl": "https://docs.aws.amazon.com/dms/latest/userguide/CHAP_Target.Neptune.html", + "Description": "**DMS Neptune endpoints** have **IAM authorization** enabled via the endpoint setting `IamAuthEnabled`.", + "Risk": "Without **IAM authorization**, migration components can interact with Neptune using broad trust, enabling unauthorized data loads, reads, or alterations.\n\nThis degrades **confidentiality** and **integrity** and increases the chance of privilege abuse and data exfiltration.", + "RelatedUrl": "", + "AdditionalURLs": [ + "https://docs.aws.amazon.com/dms/latest/userguide/CHAP_Target.Neptune.html", + "https://docs.aws.amazon.com/securityhub/latest/userguide/dms-controls.html#dms-10" + ], "Remediation": { "Code": { - "CLI": "aws dms modify-endpoint --endpoint-arn --service-access-role-arn ", - "NativeIaC": "", - "Other": "https://docs.aws.amazon.com/securityhub/latest/userguide/dms-controls.html#dms-10", + "CLI": "aws dms modify-endpoint --endpoint-arn --neptune-settings '{\"IamAuthEnabled\":true}'", + "NativeIaC": "```yaml\n# CloudFormation: Enable IAM authorization on a DMS Neptune endpoint\nResources:\n :\n Type: AWS::DMS::Endpoint\n Properties:\n EndpointType: target\n EngineName: neptune\n NeptuneSettings:\n ServiceAccessRoleArn: \n S3BucketName: \n S3BucketFolder: \n IamAuthEnabled: true # Critical: enables IAM authorization for the Neptune endpoint\n```", + "Other": "1. In the AWS Console, go to Database Migration Service > Endpoints\n2. Select the Neptune endpoint and click Modify\n3. Expand Endpoint settings (Neptune settings) and set IAM authorization to Enabled\n4. Ensure Service access role ARN is set, then click Save", "Terraform": "" }, "Recommendation": { - "Text": "Enable IAM authorization on DMS endpoints for Neptune databases by specifying a service role in the ServiceAccessRoleARN parameter.", - "Url": "https://docs.aws.amazon.com/dms/latest/userguide/CHAP_Target.Neptune.html" + "Text": "Enable **IAM authorization** on Neptune endpoints (`IamAuthEnabled=true`) and use a **least privilege** service role limited to minimal Neptune and S3 permissions.\n\nApply **defense in depth**: restrict network paths, separate duties for migration roles, and monitor access with logs and alerts.", + "Url": "https://hub.prowler.com/check/dms_endpoint_neptune_iam_authorization_enabled" } }, - "Categories": [], + "Categories": [ + "identity-access" + ], "DependsOn": [], "RelatedTo": [], "Notes": "" diff --git a/prowler/providers/aws/services/dms/dms_endpoint_redis_in_transit_encryption_enabled/dms_endpoint_redis_in_transit_encryption_enabled.metadata.json b/prowler/providers/aws/services/dms/dms_endpoint_redis_in_transit_encryption_enabled/dms_endpoint_redis_in_transit_encryption_enabled.metadata.json index 471b27aee4..2aa1ee8a00 100644 --- a/prowler/providers/aws/services/dms/dms_endpoint_redis_in_transit_encryption_enabled/dms_endpoint_redis_in_transit_encryption_enabled.metadata.json +++ b/prowler/providers/aws/services/dms/dms_endpoint_redis_in_transit_encryption_enabled/dms_endpoint_redis_in_transit_encryption_enabled.metadata.json @@ -1,31 +1,41 @@ { "Provider": "aws", "CheckID": "dms_endpoint_redis_in_transit_encryption_enabled", - "CheckTitle": "Check if DMS endpoints for Redis OSS are encrypted in transit.", + "CheckTitle": "DMS endpoint for Redis OSS is encrypted in transit", "CheckType": [ - "Software and Configuration Checks/AWS Security Best Practices" + "Software and Configuration Checks/AWS Security Best Practices/Encryption in Transit", + "Software and Configuration Checks/Industry and Regulatory Standards/NIST 800-53 Controls (USA)", + "Software and Configuration Checks/Industry and Regulatory Standards/PCI-DSS", + "Software and Configuration Checks/Industry and Regulatory Standards/ISO 27001 Controls" ], "ServiceName": "dms", "SubServiceName": "", - "ResourceIdTemplate": "arn:aws:dms:region:account-id:endpoint/endpoint-id", + "ResourceIdTemplate": "", "Severity": "medium", "ResourceType": "AwsDmsEndpoint", - "Description": "This control checks whether an AWS DMS endpoint for Redis OSS is configured with a TLS connection. The control fails if the endpoint doesn't have TLS enabled.", - "Risk": "Without TLS, data transmitted between databases may be vulnerable to interception or eavesdropping, increasing the risk of data breaches and other security incidents.", - "RelatedUrl": "https://docs.aws.amazon.com/dms/latest/userguide/CHAP_Source.Redis.html", + "Description": "**DMS Redis OSS endpoints** are assessed for the presence of **TLS** in their endpoint settings, such as `ssl-encryption`, indicating encrypted connections between the DMS replication instance and Redis.", + "Risk": "Without **TLS**, traffic between DMS and Redis can be intercepted or altered, compromising **confidentiality** and **integrity**.\n\nAttackers can perform **man-in-the-middle** interception, steal auth tokens, and inject or corrupt migrated data.", + "RelatedUrl": "", + "AdditionalURLs": [ + "https://docs.aws.amazon.com/securityhub/latest/userguide/dms-controls.html#dms-12", + "https://docs.aws.amazon.com/dms/latest/userguide/CHAP_Target.Redis.html#CHAP_Target.Redis.EndpointSettings", + "https://support.icompaas.com/support/solutions/articles/62000233450-ensure-encryption-in-transit-for-dms-endpoints-for-redis-oss" + ], "Remediation": { "Code": { - "CLI": "aws dms modify-endpoint --endpoint-arn --redis-settings '{'SslSecurityProtocol': 'ssl-encryption'}'", - "NativeIaC": "", - "Other": "https://docs.aws.amazon.com/securityhub/latest/userguide/dms-controls.html#dms-12", - "Terraform": "" + "CLI": "", + "NativeIaC": "```yaml\n# CloudFormation: Enable TLS for Redis OSS DMS endpoint\nResources:\n :\n Type: AWS::DMS::Endpoint\n Properties:\n EndpointIdentifier: \n EndpointType: target\n EngineName: redis\n RedisSettings:\n ServerName: \n Port: 6379\n AuthType: none\n SslSecurityProtocol: ssl-encryption # Critical: enables TLS for in-transit encryption\n```", + "Other": "1. In the AWS Console, go to Database Migration Service > Endpoints\n2. Select the Redis OSS endpoint and click Modify\n3. Set SSL security protocol (Encryption in transit) to \"SSL encryption\"\n4. Save changes", + "Terraform": "```hcl\n# Enable TLS for Redis OSS DMS endpoint\nresource \"aws_dms_endpoint\" \"\" {\n endpoint_id = \"\"\n endpoint_type = \"target\"\n engine_name = \"redis\"\n\n redis_settings {\n server_name = \"\"\n port = 6379\n auth_type = \"none\"\n ssl_security_protocol = \"ssl-encryption\" # Critical: enables TLS for in-transit encryption\n }\n}\n```" }, "Recommendation": { - "Text": "Enable TLS for DMS endpoints for Redis OSS to ensure encrypted communication during data migration.", - "Url": "https://docs.aws.amazon.com/dms/latest/userguide/CHAP_Target.Redis.html#CHAP_Target.Redis.EndpointSettings" + "Text": "Enable **TLS** on Redis OSS endpoints (e.g., `ssl-encryption`) and require server certificate validation. Prohibit plaintext connections, prefer private networking, and enforce **least privilege** for DMS roles to strengthen **defense in depth**.", + "Url": "https://hub.prowler.com/check/dms_endpoint_redis_in_transit_encryption_enabled" } }, - "Categories": [], + "Categories": [ + "encryption" + ], "DependsOn": [], "RelatedTo": [], "Notes": "" diff --git a/prowler/providers/aws/services/dms/dms_endpoint_ssl_enabled/dms_endpoint_ssl_enabled.metadata.json b/prowler/providers/aws/services/dms/dms_endpoint_ssl_enabled/dms_endpoint_ssl_enabled.metadata.json index 3392ac2d64..881a4423ce 100644 --- a/prowler/providers/aws/services/dms/dms_endpoint_ssl_enabled/dms_endpoint_ssl_enabled.metadata.json +++ b/prowler/providers/aws/services/dms/dms_endpoint_ssl_enabled/dms_endpoint_ssl_enabled.metadata.json @@ -1,32 +1,40 @@ { "Provider": "aws", "CheckID": "dms_endpoint_ssl_enabled", - "CheckTitle": "Ensure SSL mode is enabled in DMS endpoint", - "CheckType": ["Effects", "Data Exposure"], + "CheckTitle": "DMS endpoint has SSL enabled", + "CheckType": [ + "Software and Configuration Checks/AWS Security Best Practices", + "Effects/Data Exposure" + ], "ServiceName": "dms", - "SubServiceName": "endpoint", - "ResourceIdTemplate": "arn:partition:dms:region:account-id:endpoint:resource-id", + "SubServiceName": "", + "ResourceIdTemplate": "", "Severity": "high", "ResourceType": "AwsDmsEndpoint", - "Description": "This check ensures that SSL mode is enabled for all AWS Database Migration Service (DMS) endpoints. Enabling SSL provides encryption in transit for data transferred through these endpoints.", - "Risk": "Without SSL enabled, data transferred through DMS endpoints is not encrypted, potentially exposing sensitive information to unauthorized access or interception during transit.", - "RelatedUrl": "https://docs.aws.amazon.com/dms/latest/userguide/CHAP_Security.SSL.html", + "Description": "**AWS DMS endpoints** have their SSL/TLS mode inspected; any value other than `none` denotes encrypted connections between the replication instance and databases.\n\nSupported modes include `require`, `verify-ca`, and `verify-full`.", + "Risk": "Without TLS, data in transit can be read or altered, affecting:\n- **Confidentiality** via packet sniffing and credential leakage\n- **Integrity** through **MITM** tampering of migration streams\n- **Availability** from session hijack or task disruption", + "RelatedUrl": "", + "AdditionalURLs": [ + "https://aws.amazon.com/blogs/database/configuring-ssl-encryption-on-oracle-and-postgresql-endpoints-in-aws-dms/", + "https://docs.aws.amazon.com/dms/latest/userguide/CHAP_Security.SSL.html", + "https://docs.aws.amazon.com/securityhub/latest/userguide/dms-controls.html#dms-9" + ], "Remediation": { - "Code": { - "CLI": "aws dms modify-endpoint --endpoint-arn --ssl-mode require", - "NativeIaC": "", - "Other": "https://docs.aws.amazon.com/securityhub/latest/userguide/dms-controls.html#dms-9", - "Terraform": "" - }, - "Recommendation": { - "Text": "Enable SSL mode for all DMS endpoints. Use 'require' as the minimum SSL mode, and consider using 'verify-ca' or 'verify-full' for higher security.", - "Url": "https://docs.aws.amazon.com/dms/latest/userguide/CHAP_Security.SSL.html" - } + "Code": { + "CLI": "aws dms modify-endpoint --endpoint-arn --ssl-mode require", + "NativeIaC": "```yaml\n# CloudFormation: Set SSL on a DMS endpoint\nResources:\n :\n Type: AWS::DMS::Endpoint\n Properties:\n EndpointIdentifier: \n EndpointType: source\n EngineName: sqlserver\n ServerName: \n Port: 1433\n Username: \n Password: \n SslMode: require # CRITICAL: enables SSL (not \"none\"), fixing the finding\n```", + "Other": "1. In the AWS DMS console, go to Endpoints\n2. Select the non-compliant endpoint and choose Modify\n3. Set SSL mode to Require (or Verify-ca/Verify-full if required by your engine and certificate is available)\n4. If Verify-ca/Verify-full is selected, choose the appropriate CA certificate\n5. Save changes, then Test connection to confirm", + "Terraform": "```hcl\n# Terraform: Set SSL on a DMS endpoint\nresource \"aws_dms_endpoint\" \"\" {\n endpoint_id = \"\"\n endpoint_type = \"source\"\n engine_name = \"sqlserver\"\n server_name = \"\"\n port = 1433\n username = \"\"\n password = \"\"\n\n ssl_mode = \"require\" # CRITICAL: enables SSL (not \"none\"), fixing the finding\n}\n```" + }, + "Recommendation": { + "Text": "Configure endpoints to use SSL/TLS at least `require`; prefer `verify-ca` or `verify-full` where supported. Manage trusted CA material and rotate regularly. Apply **defense in depth** with private connectivity and strict IAM, and enforce this posture via policy-as-code and continuous validation.", + "Url": "https://hub.prowler.com/check/dms_endpoint_ssl_enabled" + } }, "Categories": [ - "encryption" + "encryption" ], "DependsOn": [], "RelatedTo": [], "Notes": "" -} \ No newline at end of file +} diff --git a/prowler/providers/aws/services/dms/dms_instance_minor_version_upgrade_enabled/dms_instance_minor_version_upgrade_enabled.metadata.json b/prowler/providers/aws/services/dms/dms_instance_minor_version_upgrade_enabled/dms_instance_minor_version_upgrade_enabled.metadata.json index 19c2686130..44bbfe4374 100644 --- a/prowler/providers/aws/services/dms/dms_instance_minor_version_upgrade_enabled/dms_instance_minor_version_upgrade_enabled.metadata.json +++ b/prowler/providers/aws/services/dms/dms_instance_minor_version_upgrade_enabled/dms_instance_minor_version_upgrade_enabled.metadata.json @@ -1,29 +1,39 @@ { "Provider": "aws", "CheckID": "dms_instance_minor_version_upgrade_enabled", - "CheckTitle": "Ensure DMS instances have auto minor version upgrade enabled.", - "CheckType": [], + "CheckTitle": "DMS replication instance has auto minor version upgrade enabled", + "CheckType": [ + "Software and Configuration Checks/Patch Management", + "Software and Configuration Checks/AWS Security Best Practices", + "Software and Configuration Checks/Industry and Regulatory Standards/AWS Foundational Security Best Practices" + ], "ServiceName": "dms", "SubServiceName": "", - "ResourceIdTemplate": "arn:aws:rdmsds:region:account-id:rep", + "ResourceIdTemplate": "", "Severity": "medium", "ResourceType": "AwsDmsReplicationInstance", - "Description": "Ensure DMS instances have auto minor version upgrade enabled.", - "Risk": "Ensure that your Amazon Database Migration Service (DMS) replication instances have the Auto Minor Version Upgrade feature enabled in order to receive automatically minor engine upgrades.", - "RelatedUrl": "https://docs.aws.amazon.com/securityhub/latest/userguide/dms-controls.html#dms-6", + "Description": "**AWS DMS replication instances** are evaluated for the `auto_minor_version_upgrade` setting to confirm **automatic minor engine updates** are enabled during the maintenance window.", + "Risk": "Without **automatic minor upgrades**, DMS engines can miss security patches and fixes, enabling exploitation of known flaws and instability.\n- Confidentiality: exposure via unpatched components\n- Integrity: replication errors or data drift\n- Availability: outages during migration or CDC", + "RelatedUrl": "", + "AdditionalURLs": [ + "https://docs.aws.amazon.com/securityhub/latest/userguide/dms-controls.html#dms-6", + "https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/DMS/auto-minor-version-upgrade.html" + ], "Remediation": { "Code": { "CLI": "aws dms modify-replication-instance --region --replication-instance-arn arn:aws:dms:::rep: --auto-minor-version-upgrade --apply-immediately", - "NativeIaC": "https://www.trendmicro.com/cloudoneconformity-staging/knowledge-base/aws/DMS/auto-minor-version-upgrade.html#", - "Other": "https://www.trendmicro.com/cloudoneconformity-staging/knowledge-base/aws/DMS/auto-minor-version-upgrade.html#", - "Terraform": "https://www.trendmicro.com/cloudoneconformity-staging/knowledge-base/aws/DMS/auto-minor-version-upgrade.html#" + "NativeIaC": "```yaml\n# CloudFormation: Enable auto minor version upgrade on a DMS replication instance\nResources:\n :\n Type: AWS::DMS::ReplicationInstance\n Properties:\n ReplicationInstanceIdentifier: \n ReplicationInstanceClass: dms.t3.micro\n AutoMinorVersionUpgrade: true # CRITICAL: turns on automatic minor version upgrades\n```", + "Other": "1. Open the AWS Console and go to Database Migration Service (DMS)\n2. Click Replication instances and select your instance\n3. Choose Actions > Modify\n4. Check Auto minor version upgrade\n5. Select Apply immediately\n6. Click Modify to save", + "Terraform": "```hcl\n# Terraform: Enable auto minor version upgrade on a DMS replication instance\nresource \"aws_dms_replication_instance\" \"\" {\n replication_instance_id = \"\"\n replication_instance_class = \"dms.t3.micro\"\n auto_minor_version_upgrade = true # CRITICAL: turns on automatic minor version upgrades\n}\n```" }, "Recommendation": { - "Text": "Enable auto minor version upgrade for all DMS replication instances.", - "Url": "https://docs.aws.amazon.com/securityhub/latest/userguide/dms-controls.html#dms-6" + "Text": "Enable `auto_minor_version_upgrade` on all replication instances to maintain **continuous patching**.\n- Set a maintenance window and validate in non-prod\n- Monitor release notes and health metrics\n- Enforce **least privilege** for change control\n- Keep **backups** for rollback", + "Url": "https://hub.prowler.com/check/dms_instance_minor_version_upgrade_enabled" } }, - "Categories": [], + "Categories": [ + "vulnerabilities" + ], "DependsOn": [], "RelatedTo": [], "Notes": "" diff --git a/prowler/providers/aws/services/dms/dms_instance_multi_az_enabled/dms_instance_multi_az_enabled.metadata.json b/prowler/providers/aws/services/dms/dms_instance_multi_az_enabled/dms_instance_multi_az_enabled.metadata.json index 65d5cd4336..e460711cd7 100644 --- a/prowler/providers/aws/services/dms/dms_instance_multi_az_enabled/dms_instance_multi_az_enabled.metadata.json +++ b/prowler/providers/aws/services/dms/dms_instance_multi_az_enabled/dms_instance_multi_az_enabled.metadata.json @@ -1,30 +1,37 @@ { "Provider": "aws", "CheckID": "dms_instance_multi_az_enabled", - "CheckTitle": "Ensure DMS instances have multi az enabled.", - "CheckType": [], + "CheckTitle": "DMS replication instance has Multi-AZ enabled", + "CheckType": [ + "Software and Configuration Checks/AWS Security Best Practices", + "Effects/Denial of Service" + ], "ServiceName": "dms", "SubServiceName": "", - "ResourceIdTemplate": "arn:aws:rdmsds:region:account-id:rep", + "ResourceIdTemplate": "", "Severity": "medium", "ResourceType": "AwsDmsReplicationInstance", - "Description": "Ensure DMS instances have multi az enabled.", - "Risk": "Ensure that your Amazon Database Migration Service (DMS) replication instances are using Multi-AZ deployment configurations to provide High Availability (HA) through automatic failover to standby replicas in the event of a failure such as an Availability Zone (AZ) outage, an internal hardware or network outage, a software failure or in case of a planned maintenance session.", - "RelatedUrl": "https://www.trendmicro.com/cloudoneconformity-staging/knowledge-base/aws/DMS/multi-az.html#", + "Description": "**AWS DMS replication instances** are evaluated for **Multi-AZ** configuration. Instances with `multi_az` enabled are treated as having a cross-AZ standby; those without it are identified as single-AZ.", + "Risk": "Without **Multi-AZ**, a single-AZ failure or maintenance event can halt migrations, causing extended downtime (**availability**) and replication gaps or rollbacks (**integrity**). Tasks may stall, increase cutover risk, and require manual recovery when the replication instance is unavailable.", + "RelatedUrl": "", + "AdditionalURLs": [ + "https://docs.aws.amazon.com/dms/latest/userguide/CHAP_ReplicationInstance.html", + "https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/DMS/multi-az.html" + ], "Remediation": { "Code": { - "CLI": "aws dms modify-replication-instance --region --replication-instance-arn arn:aws:dms:::rep: --multi-az --apply-immediately", - "NativeIaC": "https://www.trendmicro.com/cloudoneconformity-staging/knowledge-base/aws/DMS/multi-az.html#", - "Other": "https://www.trendmicro.com/cloudoneconformity-staging/knowledge-base/aws/DMS/multi-az.html#", - "Terraform": "https://www.trendmicro.com/cloudoneconformity-staging/knowledge-base/aws/DMS/multi-az.html#" + "CLI": "aws dms modify-replication-instance --replication-instance-arn arn:aws:dms:::rep: --multi-az --apply-immediately", + "NativeIaC": "```yaml\n# CloudFormation: enable Multi-AZ on a DMS replication instance\nResources:\n :\n Type: AWS::DMS::ReplicationInstance\n Properties:\n ReplicationInstanceClass: dms.t3.micro\n MultiAZ: true # Critical: enables Multi-AZ to pass the check\n```", + "Other": "1. Open the AWS DMS console\n2. Go to Replication instances and select your instance\n3. Click Modify\n4. Check Multi-AZ\n5. Check Apply immediately\n6. Click Modify to save", + "Terraform": "```hcl\n# Enable Multi-AZ on a DMS replication instance\nresource \"aws_dms_replication_instance\" \"\" {\n replication_instance_id = \"\"\n replication_instance_class = \"dms.t3.micro\"\n multi_az = true # Critical: enables Multi-AZ to pass the check\n}\n```" }, "Recommendation": { - "Text": "Enable multi az for all DMS replication instances.", - "Url": "https://www.trendmicro.com/cloudoneconformity-staging/knowledge-base/aws/DMS/multi-az.html#" + "Text": "Enable **Multi-AZ** (set `multi_az` to `true`) on DMS replication instances that handle production or time-sensitive migrations to ensure redundancy and automatic failover.\n\nApply HA principles: distribute across AZs, test failover, monitor health, and plan maintenance to minimize impact.", + "Url": "https://hub.prowler.com/check/dms_instance_multi_az_enabled" } }, "Categories": [ - "redundancy" + "resilience" ], "DependsOn": [], "RelatedTo": [], diff --git a/prowler/providers/aws/services/dms/dms_instance_no_public_access/dms_instance_no_public_access.metadata.json b/prowler/providers/aws/services/dms/dms_instance_no_public_access/dms_instance_no_public_access.metadata.json index 7692268a5c..9a7917e3a5 100644 --- a/prowler/providers/aws/services/dms/dms_instance_no_public_access/dms_instance_no_public_access.metadata.json +++ b/prowler/providers/aws/services/dms/dms_instance_no_public_access/dms_instance_no_public_access.metadata.json @@ -1,26 +1,37 @@ { "Provider": "aws", "CheckID": "dms_instance_no_public_access", - "CheckTitle": "Ensure DMS instances are not publicly accessible.", - "CheckType": [], + "CheckTitle": "DMS replication instance is not publicly exposed to the Internet", + "CheckType": [ + "Software and Configuration Checks/AWS Security Best Practices/Network Reachability", + "Software and Configuration Checks/Industry and Regulatory Standards/AWS Foundational Security Best Practices", + "Software and Configuration Checks/Industry and Regulatory Standards/CIS AWS Foundations Benchmark", + "TTPs/Initial Access" + ], "ServiceName": "dms", "SubServiceName": "", - "ResourceIdTemplate": "arn:aws:rdmsds:region:account-id:rep", + "ResourceIdTemplate": "", "Severity": "critical", "ResourceType": "AwsDmsReplicationInstance", - "Description": "Ensure DMS instances are not publicly accessible.", - "Risk": "Ensure that your Amazon Database Migration Service (DMS) are not publicly accessible from the Internet in order to avoid exposing private data and minimize security risks. A DMS replication instance should have a private IP address and the Publicly Accessible feature disabled when both the source and the target databases are in the same network that is connected to the instance's VPC through a VPN, VPC peering connection, or using an AWS Direct Connect dedicated connection.", - "RelatedUrl": "https://docs.aws.amazon.com/securityhub/latest/userguide/dms-controls.html#dms-1", + "Description": "**AWS DMS replication instances** are evaluated for **public exposure**. Exposure is identified when `PubliclyAccessible` is enabled and an attached security group allows inbound traffic from any address. Private or allowlisted instances are not considered exposed.", + "Risk": "Publicly reachable replication instances threaten:\n- Confidentiality: migration data and credentials can be intercepted or exfiltrated.\n- Integrity: attackers may alter tasks or inject records.\n- Availability: abuse or DDoS can stall replication and delay cutovers.", + "RelatedUrl": "", + "AdditionalURLs": [ + "https://docs.aws.amazon.com/securityhub/latest/userguide/dms-controls.html#dms-1", + "https://docs.aws.amazon.com/amazonq/detector-library/terraform/restrict-public-access-dms-terraform/", + "https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/DMS/publicly-accessible.html", + "https://support.icompaas.com/support/solutions/articles/62000233448-ensure-dms-instances-are-not-publicly-accessible" + ], "Remediation": { "Code": { "CLI": "", - "NativeIaC": "https://www.trendmicro.com/cloudoneconformity-staging/knowledge-base/aws/DMS/publicly-accessible.html#", - "Other": "https://www.trendmicro.com/cloudoneconformity-staging/knowledge-base/aws/DMS/publicly-accessible.html#", - "Terraform": "https://www.trendmicro.com/cloudoneconformity-staging/knowledge-base/aws/DMS/publicly-accessible.html#" + "NativeIaC": "```yaml\n# CloudFormation: DMS instance not publicly accessible\nResources:\n :\n Type: AWS::DMS::ReplicationInstance\n Properties:\n ReplicationInstanceClass: dms.t3.micro\n PubliclyAccessible: false # Critical: disables public access to prevent Internet exposure\n```", + "Other": "1. In the AWS Console, open Database Migration Service > Replication instances and select the instance\n2. In Details > Networking, click each attached Security Group ID to open it in the EC2 console\n3. In Inbound rules, delete any rule with Source 0.0.0.0/0 or ::/0\n4. Save rules for each security group", + "Terraform": "```hcl\n# DMS instance not publicly accessible\nresource \"aws_dms_replication_instance\" \"\" {\n replication_instance_id = \"\"\n replication_instance_class = \"dms.t3.micro\"\n publicly_accessible = false # Critical: disables public access to prevent Internet exposure\n}\n```" }, "Recommendation": { - "Text": "Restrict DMS Replication instances security groups to only required IPs, or re-create these instances that is only accessible privately.", - "Url": "https://docs.aws.amazon.com/securityhub/latest/userguide/dms-controls.html#dms-1" + "Text": "Adopt a **private-only** design:\n- Disable `PubliclyAccessible`; place instances in private subnets.\n- Enforce **least privilege** security groups (no `0.0.0.0/0`); allow only required sources/ports.\n- Provide access via **VPN**, peering, or Direct Connect.\n- Layer controls (ACLs, monitoring) and restrict IAM to necessary actions.", + "Url": "https://hub.prowler.com/check/dms_instance_no_public_access" } }, "Categories": [ diff --git a/prowler/providers/aws/services/dms/dms_replication_task_source_logging_enabled/dms_replication_task_source_logging_enabled.metadata.json b/prowler/providers/aws/services/dms/dms_replication_task_source_logging_enabled/dms_replication_task_source_logging_enabled.metadata.json index 981a51c73b..43c55ab39d 100644 --- a/prowler/providers/aws/services/dms/dms_replication_task_source_logging_enabled/dms_replication_task_source_logging_enabled.metadata.json +++ b/prowler/providers/aws/services/dms/dms_replication_task_source_logging_enabled/dms_replication_task_source_logging_enabled.metadata.json @@ -1,31 +1,39 @@ { "Provider": "aws", "CheckID": "dms_replication_task_source_logging_enabled", - "CheckTitle": "Check if DMS replication tasks for the source database have logging enabled.", + "CheckTitle": "DMS replication task has logging enabled and SOURCE_CAPTURE and SOURCE_UNLOAD components set to at least Default severity", "CheckType": [ - "Software and Configuration Checks/AWS Security Best Practices" + "Software and Configuration Checks/AWS Security Best Practices", + "TTPs/Defense Evasion" ], "ServiceName": "dms", "SubServiceName": "", - "ResourceIdTemplate": "arn:aws:dms:region:account-id:task/task-id", + "ResourceIdTemplate": "", "Severity": "medium", "ResourceType": "AwsDmsReplicationTask", - "Description": "This control checks whether logging is enabled with the minimum severity level of LOGGER_SEVERITY_DEFAULT for DMS replication tasks SOURCE_CAPTURE and SOURCE_UNLOAD. The control fails if logging isn't enabled for these tasks or if the minimum severity level is less than LOGGER_SEVERITY_DEFAULT.", - "Risk": "Without logging enabled, issues in data migration may go undetected, affecting the integrity and compliance of replicated data.", - "RelatedUrl": "https://docs.aws.amazon.com/dms/latest/userguide/CHAP_Monitoring.html#CHAP_Monitoring.ManagingLogs", + "Description": "**AWS DMS replication tasks** have **logging enabled** and configure `SOURCE_CAPTURE` and `SOURCE_UNLOAD` with severity at least `LOGGER_SEVERITY_DEFAULT` (or higher: `LOGGER_SEVERITY_DEBUG`, `LOGGER_SEVERITY_DETAILED_DEBUG`).", + "Risk": "Missing or low-severity source logs hinder visibility into **CDC** and full-load activity, risking undetected errors, stalls, or tampering. This can cause silent **data drift**, broken lineage, and failed recoveries, undermining **integrity** and **availability** and weakening auditability during investigations.", + "RelatedUrl": "", + "AdditionalURLs": [ + "https://docs.aws.amazon.com/dms/latest/userguide/CHAP_Monitoring.html", + "https://repost.aws/knowledge-center/dms-debug-logging", + "https://docs.aws.amazon.com/securityhub/latest/userguide/dms-controls.html#dms-8" + ], "Remediation": { "Code": { - "CLI": "aws dms modify-replication-task --replication-task-arn --task-settings '{\"Logging\":{\"EnableLogging\":true,\"LogComponents\":[{\"Id\":\"SOURCE_CAPTURE\",\"Severity\":\"LOGGER_SEVERITY_DEFAULT\"},{\"Id\":\"SOURCE_UNLOAD\",\"Severity\":\"LOGGER_SEVERITY_DEFAULT\"}]}}'", - "NativeIaC": "", - "Other": "https://docs.aws.amazon.com/securityhub/latest/userguide/dms-controls.html#dms-8", - "Terraform": "" + "CLI": "aws dms modify-replication-task --replication-task-arn --replication-task-settings '{\"Logging\":{\"EnableLogging\":true,\"LogComponents\":[{\"Id\":\"SOURCE_CAPTURE\",\"Severity\":\"LOGGER_SEVERITY_DEFAULT\"},{\"Id\":\"SOURCE_UNLOAD\",\"Severity\":\"LOGGER_SEVERITY_DEFAULT\"}]}}'", + "NativeIaC": "```yaml\n# CloudFormation: enable DMS source logging at minimum DEFAULT severity\nResources:\n :\n Type: AWS::DMS::ReplicationTask\n Properties:\n ReplicationInstanceArn: \n SourceEndpointArn: \n TargetEndpointArn: \n MigrationType: full-load\n TableMappings: '{\"rules\":[]}'\n # Critical: Enables logging and sets SOURCE components to at least DEFAULT\n ReplicationTaskSettings: |\n {\n \"Logging\": {\n \"EnableLogging\": true,\n \"LogComponents\": [\n {\"Id\": \"SOURCE_CAPTURE\", \"Severity\": \"LOGGER_SEVERITY_DEFAULT\"},\n {\"Id\": \"SOURCE_UNLOAD\", \"Severity\": \"LOGGER_SEVERITY_DEFAULT\"}\n ]\n }\n }\n```", + "Other": "1. In the AWS console, go to Database Migration Service > Database migration tasks\n2. Select the task and choose Modify\n3. Click Modify task logging\n4. Turn on Enable logging\n5. For SOURCE_CAPTURE and SOURCE_UNLOAD, set Severity to Default (or higher)\n6. Save/Modify to apply", + "Terraform": "```hcl\n# Enable DMS source logging at minimum DEFAULT severity\nresource \"aws_dms_replication_task\" \"\" {\n replication_instance_arn = \"\"\n source_endpoint_arn = \"\"\n target_endpoint_arn = \"\"\n migration_type = \"full-load\"\n table_mappings = \"{\\\"rules\\\":[]}\"\n\n # Critical: Enables logging and sets SOURCE components to at least DEFAULT\n replication_task_settings = < --task-settings '{\"Logging\":{\"EnableLogging\":true,\"LogComponents\":[{\"Id\":\"TARGET_APPLY\",\"Severity\":\"LOGGER_SEVERITY_DEFAULT\"},{\"Id\":\"TARGET_LOAD\",\"Severity\":\"LOGGER_SEVERITY_DEFAULT\"}]}}'", - "NativeIaC": "", - "Other": "https://docs.aws.amazon.com/securityhub/latest/userguide/dms-controls.html#dms-7", - "Terraform": "" + "CLI": "aws dms modify-replication-task --replication-task-arn --replication-task-settings '{\"Logging\":{\"EnableLogging\":true,\"LogComponents\":[{\"Id\":\"TARGET_APPLY\",\"Severity\":\"LOGGER_SEVERITY_DEFAULT\"},{\"Id\":\"TARGET_LOAD\",\"Severity\":\"LOGGER_SEVERITY_DEFAULT\"}]}}'", + "NativeIaC": "```yaml\n# CloudFormation: enable DMS task logging for target components\nResources:\n :\n Type: AWS::DMS::ReplicationTask\n Properties:\n ReplicationInstanceArn: \n SourceEndpointArn: \n TargetEndpointArn: \n MigrationType: full-load\n TableMappings: |\n {\"rules\":[{\"rule-type\":\"selection\",\"rule-id\":\"1\",\"rule-name\":\"1\",\"object-locator\":{\"schema-name\":\"%\",\"table-name\":\"%\"},\"rule-action\":\"include\"}]}\n ReplicationTaskSettings: |\n {\"Logging\":{\"EnableLogging\":true, \"LogComponents\":[\n {\"Id\":\"TARGET_APPLY\",\"Severity\":\"LOGGER_SEVERITY_DEFAULT\"}, # Critical: ensure TARGET_APPLY logging at default\n {\"Id\":\"TARGET_LOAD\",\"Severity\":\"LOGGER_SEVERITY_DEFAULT\"} # Critical: ensure TARGET_LOAD logging at default\n ]}}\n```", + "Other": "1. Open the AWS DMS console and go to Database migration tasks\n2. Select the replication task and choose Modify\n3. Expand Task settings (JSON) or Logging\n4. Enable CloudWatch logs (EnableLogging = true)\n5. Set log components:\n - TARGET_APPLY severity: DEFAULT\n - TARGET_LOAD severity: DEFAULT\n6. Save changes (Modify task), then rerun the task if required", + "Terraform": "```hcl\n# Enable DMS task logging for target components\nresource \"aws_dms_replication_task\" \"\" {\n replication_task_id = \"\"\n replication_instance_arn = \"\"\n source_endpoint_arn = \"\"\n target_endpoint_arn = \"\"\n migration_type = \"full-load\"\n table_mappings = jsonencode({ rules = [{\n \"rule-type\" : \"selection\", \"rule-id\" : \"1\", \"rule-name\" : \"1\",\n \"object-locator\" : { \"schema-name\" : \"%\", \"table-name\" : \"%\" },\n \"rule-action\" : \"include\"\n }]} )\n\n # Critical: enables logging and sets TARGET_APPLY and TARGET_LOAD to minimum required severity\n replication_task_settings = jsonencode({\n Logging = {\n EnableLogging = true\n LogComponents = [\n { Id = \"TARGET_APPLY\", Severity = \"LOGGER_SEVERITY_DEFAULT\" },\n { Id = \"TARGET_LOAD\", Severity = \"LOGGER_SEVERITY_DEFAULT\" }\n ]\n }\n })\n}\n```" }, "Recommendation": { - "Text": "Enable logging for target database DMS replication tasks with a minimum severity level of LOGGER_SEVERITY_DEFAULT.", - "Url": "https://docs.aws.amazon.com/dms/latest/userguide/CHAP_Tasks.CustomizingTasks.TaskSettings.Logging.html" + "Text": "Enable and maintain **CloudWatch logging** at `LOGGER_SEVERITY_DEFAULT` or higher for target components:\n- Configure `TARGET_APPLY` and `TARGET_LOAD`\n- Enforce least-privilege log access\n- Monitor logs/alerts for anomalies\n- Standardize task settings and validate data for **defense in depth**", + "Url": "https://hub.prowler.com/check/dms_replication_task_target_logging_enabled" } }, - "Categories": [], + "Categories": [ + "logging" + ], "DependsOn": [], "RelatedTo": [], "Notes": "" diff --git a/prowler/providers/aws/services/efs/efs_access_point_enforce_root_directory/efs_access_point_enforce_root_directory.metadata.json b/prowler/providers/aws/services/efs/efs_access_point_enforce_root_directory/efs_access_point_enforce_root_directory.metadata.json index b02871bdd3..b4f6fcd4c4 100644 --- a/prowler/providers/aws/services/efs/efs_access_point_enforce_root_directory/efs_access_point_enforce_root_directory.metadata.json +++ b/prowler/providers/aws/services/efs/efs_access_point_enforce_root_directory/efs_access_point_enforce_root_directory.metadata.json @@ -1,28 +1,34 @@ { "Provider": "aws", "CheckID": "efs_access_point_enforce_root_directory", - "CheckTitle": "EFS access points should enforce a root directory", + "CheckTitle": "EFS file system has no access points allowing access to the root directory", "CheckType": [ - "Software and Configuration Checks/AWS Security Best Practices" + "Software and Configuration Checks/AWS Security Best Practices", + "Software and Configuration Checks/Industry and Regulatory Standards/AWS Foundational Security Best Practices", + "Effects/Data Exposure" ], "ServiceName": "efs", - "SubServiceName": "access-point", - "ResourceIdTemplate": "arn:aws:elasticfilesystem:{region}:{account-id}:access-point/{access-point-id}", + "SubServiceName": "", + "ResourceIdTemplate": "", "Severity": "medium", "ResourceType": "AwsEfsAccessPoint", - "Description": "This control checks if Amazon EFS access points are configured to enforce a root directory. The control fails if the value of Path is set to / (the default root directory of the file system).", - "Risk": "Access points without enforced root directories can potentially expose the entire file system's root directory to clients, which may result in unauthorized access.", - "RelatedUrl": "https://docs.aws.amazon.com/config/latest/developerguide/efs-access-point-enforce-root-directory.html", + "Description": "**Amazon EFS access points** are evaluated to ensure they enforce a non-root directory. The check identifies access points whose configured root directory `Path` is `/`, meaning clients would mount the file system's root instead of a scoped subdirectory.", + "Risk": "Exposing the file system root via an access point undermines **confidentiality** and **integrity** by allowing traversal beyond intended datasets. Attackers or misconfigured apps could:\n- Read sensitive directories\n- Modify or delete shared data\n- Pivot across tenants, impacting **availability**", + "RelatedUrl": "", + "AdditionalURLs": [ + "https://docs.aws.amazon.com/efs/latest/ug/enforce-root-directory-access-point.html", + "https://docs.aws.amazon.com/securityhub/latest/userguide/efs-controls.html#efs-3" + ], "Remediation": { "Code": { - "CLI": "aws efs update-access-point --access-point-id --root-directory Path=", - "NativeIaC": "", - "Other": "https://docs.aws.amazon.com/securityhub/latest/userguide/efs-controls.html#efs-3", - "Terraform": "" + "CLI": "aws efs delete-access-point --access-point-id ", + "NativeIaC": "```yaml\n# CloudFormation: EFS access point enforcing a non-root directory\nResources:\n :\n Type: AWS::EFS::AccessPoint\n Properties:\n FileSystemId: \n RootDirectory:\n Path: /data # Critical: set to a non-root path to avoid \"/\" and pass the check\n # This enforces the access point root to /data instead of the file system root\n```", + "Other": "1. In the AWS Console, go to EFS > Access points\n2. Select the access point showing Root directory as /\n3. Click Delete and confirm\n4. Click Create access point\n5. Select the file system and set Root directory Path to a non-root path (for example, /data)\n6. Click Create access point", + "Terraform": "```hcl\n# Terraform: EFS access point enforcing a non-root directory\nresource \"aws_efs_access_point\" \"\" {\n file_system_id = \"\"\n\n root_directory {\n path = \"/data\" # Critical: not \"/\"; enforces a subdirectory as root to pass the check\n }\n}\n```" }, "Recommendation": { - "Text": "Update the EFS access point to enforce a non-root directory. This ensures clients can only access a specified subdirectory.", - "Url": "https://docs.aws.amazon.com/efs/latest/ug/enforce-root-directory-access-point.html" + "Text": "Apply **least privilege**: set each access point `Path` to a dedicated subdirectory and avoid `/`.\n- Use per-application access points\n- Enforce POSIX identity and directory permissions\n- Layer controls (network segmentation, monitoring) for **defense in depth**", + "Url": "https://hub.prowler.com/check/efs_access_point_enforce_root_directory" } }, "Categories": [ diff --git a/prowler/providers/aws/services/efs/efs_access_point_enforce_user_identity/efs_access_point_enforce_user_identity.metadata.json b/prowler/providers/aws/services/efs/efs_access_point_enforce_user_identity/efs_access_point_enforce_user_identity.metadata.json index fa20750f87..c7d0b5b0a4 100644 --- a/prowler/providers/aws/services/efs/efs_access_point_enforce_user_identity/efs_access_point_enforce_user_identity.metadata.json +++ b/prowler/providers/aws/services/efs/efs_access_point_enforce_user_identity/efs_access_point_enforce_user_identity.metadata.json @@ -1,32 +1,42 @@ { "Provider": "aws", "CheckID": "efs_access_point_enforce_user_identity", - "CheckTitle": "EFS access points should enforce a user identity", + "CheckTitle": "EFS file system has all access points with a defined POSIX user", "CheckType": [ - "Software and Configuration Checks/AWS Security Best Practices" + "Software and Configuration Checks/AWS Security Best Practices", + "Software and Configuration Checks/Industry and Regulatory Standards/AWS Foundational Security Best Practices", + "Effects/Data Exposure", + "TTPs/Privilege Escalation" ], "ServiceName": "efs", "SubServiceName": "", - "ResourceIdTemplate": "arn:aws:elasticfilesystem:{region}:{account-id}:access-point/{access-point-id}", + "ResourceIdTemplate": "", "Severity": "medium", "ResourceType": "AwsEfsAccessPoint", - "Description": "This control checks whether Amazon EFS access points are configured to enforce a user identity. This control fails if a POSIX user identity is not defined while creating the EFS access point.", - "Risk": "Without enforcing a user identity, access to the file system can become less controlled, leading to potential unauthorized access or modifications.", - "RelatedUrl": "https://docs.aws.amazon.com/config/latest/developerguide/efs-access-point-enforce-user-identity.html", + "Description": "**Amazon EFS access points** are evaluated for a defined **POSIX user** (`uid`, `gid`, optional secondary groups). The check inspects each access point on a file system and flags those without a configured POSIX user identity.", + "Risk": "Without enforced **POSIX identity**, NFS clients can supply arbitrary UIDs/GIDs, enabling impersonation, unauthorized reads/writes, and ownership spoofing. This undermines **confidentiality** and **integrity** of shared data and can enable **lateral movement** across applications sharing the file system.", + "RelatedUrl": "", + "AdditionalURLs": [ + "https://docs.aws.amazon.com/efs/latest/ug/efs-access-points.html", + "https://repost.aws/knowledge-center/efs-access-points-directory-access", + "https://www.plerion.com/cloud-knowledge-base/efs-access-points-should-be-configured-to-enforce-a-user-identity", + "https://docs.aws.amazon.com/efs/latest/ug/enforce-identity-access-points.html", + "https://docs.aws.amazon.com/securityhub/latest/userguide/efs-controls.html#efs-4" + ], "Remediation": { "Code": { - "CLI": "aws efs create-access-point --file-system-id --posix-user Uid=,Gid=", - "NativeIaC": "", - "Other": "https://docs.aws.amazon.com/securityhub/latest/userguide/efs-controls.html#efs-4", - "Terraform": "" + "CLI": "", + "NativeIaC": "```yaml\nResources:\n ExampleAccessPoint:\n Type: AWS::EFS::AccessPoint\n Properties:\n FileSystemId: \"\"\n PosixUser: # Critical: enforces a POSIX user for all requests via this access point\n Uid: \"\" # Critical: POSIX user ID enforced\n Gid: \"\" # Critical: POSIX group ID enforced\n```", + "Other": "1. In the AWS Console, go to Amazon EFS > Access points\n2. Click Create access point, select the file system, and set POSIX user: enter User ID and Group ID\n3. Click Create access point\n4. Update clients to mount using the new access point ID\n5. Delete the old access point(s) that lack a POSIX user", + "Terraform": "```hcl\nresource \"aws_efs_access_point\" \"example\" {\n file_system_id = \"\"\n\n # Critical: enforces a POSIX user for all requests via this access point\n posix_user {\n uid = 1000 # Critical: user ID enforced\n gid = 1000 # Critical: group ID enforced\n }\n}\n```" }, "Recommendation": { - "Text": "Create or update the EFS access point to enforce a user identity using POSIX attributes for Uid and Gid.", - "Url": "https://docs.aws.amazon.com/efs/latest/ug/enforce-identity-access-points.html" + "Text": "Enforce a **POSIX user identity** on every access point using least-privilege `uid`/`gid` (avoid `0`). Apply **separation of duties** with dedicated access points per application and minimal groups. Use **IAM** to require access point usage and add **defense in depth** by enforcing a restricted root directory.", + "Url": "https://hub.prowler.com/check/efs_access_point_enforce_user_identity" } }, "Categories": [ - "trustboundaries" + "identity-access" ], "DependsOn": [], "RelatedTo": [], diff --git a/prowler/providers/aws/services/efs/efs_encryption_at_rest_enabled/efs_encryption_at_rest_enabled.metadata.json b/prowler/providers/aws/services/efs/efs_encryption_at_rest_enabled/efs_encryption_at_rest_enabled.metadata.json index b6c6b8a207..84c3c79f23 100644 --- a/prowler/providers/aws/services/efs/efs_encryption_at_rest_enabled/efs_encryption_at_rest_enabled.metadata.json +++ b/prowler/providers/aws/services/efs/efs_encryption_at_rest_enabled/efs_encryption_at_rest_enabled.metadata.json @@ -1,30 +1,40 @@ { "Provider": "aws", "CheckID": "efs_encryption_at_rest_enabled", - "CheckTitle": "Check if EFS protects sensitive data with encryption at rest", + "CheckTitle": "EFS file system has encryption at rest enabled", "CheckType": [ - "Protect", - "Data protection", - "Encryption of data at rest" + "Software and Configuration Checks/AWS Security Best Practices", + "Software and Configuration Checks/Industry and Regulatory Standards/AWS Foundational Security Best Practices", + "Software and Configuration Checks/Industry and Regulatory Standards/NIST 800-53 Controls (USA)", + "Software and Configuration Checks/Industry and Regulatory Standards/NIST CSF Controls (USA)", + "Software and Configuration Checks/Industry and Regulatory Standards/PCI-DSS", + "Software and Configuration Checks/Industry and Regulatory Standards/HIPAA Controls (USA)", + "Software and Configuration Checks/Industry and Regulatory Standards/ISO 27001 Controls", + "Effects/Data Exposure" ], "ServiceName": "efs", "SubServiceName": "", - "ResourceIdTemplate": "arn:partition:service:region:account-id:resource-id", + "ResourceIdTemplate": "", "Severity": "medium", "ResourceType": "AwsEfsFileSystem", - "Description": "Check if EFS protects sensitive data with encryption at rest", - "Risk": "EFS should be encrypted at rest to prevent exposure of sensitive data to bad actors", + "Description": "**Amazon EFS file system** has **encryption at rest** enabled using AWS KMS to protect file data and metadata stored on the service", + "Risk": "Without encryption at rest, EFS contents can be read from storage media, backups, or compromised hosts, eroding **confidentiality** and enabling offline exfiltration. Privileged compromise also allows covert data harvesting or manipulation, threatening **integrity** of files.", "RelatedUrl": "", + "AdditionalURLs": [ + "https://repost.aws/knowledge-center/efs-turn-on-encryption-at-rest", + "https://docs.aws.amazon.com/efs/latest/ug/EFSKMS.html", + "https://docs.aws.amazon.com/efs/latest/ug/encryption-at-rest.html" + ], "Remediation": { "Code": { - "CLI": "aws efs create-file-system --creation-token $(uuidgen) --performance-mode generalPurpose --encrypted --kms-key-id user/customer-managedCMKalias", - "NativeIaC": "https://docs.prowler.com/checks/aws/general-policies/general_17#cloudformation", - "Other": "", - "Terraform": "https://docs.prowler.com/checks/aws/general-policies/general_17#terraform" + "CLI": "", + "NativeIaC": "```yaml\n# CloudFormation: Create an EFS file system with encryption at rest enabled\nResources:\n :\n Type: AWS::EFS::FileSystem\n Properties:\n Encrypted: true # Critical: enables encryption at rest so the check passes\n```", + "Other": "1. In the AWS Console, go to Amazon EFS\n2. Click Create file system\n3. Check Enable encryption (leave default key or choose a KMS key if required)\n4. Click Create\n5. Migrate data from the unencrypted file system to the new encrypted one\n6. Delete the unencrypted file system to clear the failing finding", + "Terraform": "```hcl\n# Terraform: Create an EFS file system with encryption at rest enabled\nresource \"aws_efs_file_system\" \"\" {\n encrypted = true # Critical: enables encryption at rest so the check passes\n}\n```" }, "Recommendation": { - "Text": "Ensure that encryption at rest is enabled for EFS file systems. Encryption at rest can only be enabled during the file system creation.", - "Url": "https://docs.aws.amazon.com/efs/latest/ug/encryption-at-rest.html" + "Text": "Enable **encryption at rest** for all EFS file systems and prefer **customer-managed KMS keys** for control, rotation, and audit. Apply **least privilege** to key policies and separate key management duties. *For existing unencrypted data*, migrate to a new encrypted file system. Enforce creation policies (IAM/SCP) to prevent non-encrypted deployments.", + "Url": "https://hub.prowler.com/check/efs_encryption_at_rest_enabled" } }, "Categories": [ diff --git a/prowler/providers/aws/services/efs/efs_have_backup_enabled/efs_have_backup_enabled.metadata.json b/prowler/providers/aws/services/efs/efs_have_backup_enabled/efs_have_backup_enabled.metadata.json index d1b62abbb0..c02a39f1cc 100644 --- a/prowler/providers/aws/services/efs/efs_have_backup_enabled/efs_have_backup_enabled.metadata.json +++ b/prowler/providers/aws/services/efs/efs_have_backup_enabled/efs_have_backup_enabled.metadata.json @@ -1,33 +1,39 @@ { "Provider": "aws", "CheckID": "efs_have_backup_enabled", - "CheckTitle": "Check if EFS File systems have backup enabled", + "CheckTitle": "EFS file system has backup enabled", "CheckType": [ - "Recover", - "Resilience", - "Backup" + "Software and Configuration Checks/AWS Security Best Practices", + "Software and Configuration Checks/Industry and Regulatory Standards/AWS Foundational Security Best Practices", + "Effects/Data Destruction" ], "ServiceName": "efs", "SubServiceName": "", - "ResourceIdTemplate": "arn:partition:service:region:account-id:resource-id", + "ResourceIdTemplate": "", "Severity": "medium", "ResourceType": "AwsEfsFileSystem", - "Description": "Check if EFS File systems have backup enabled", - "Risk": "If backup is not enabled, data is vulnerable. Human error or bad actors could erase or modify data.", + "Description": "**Amazon EFS file systems** are assessed for automated backups configured via the `backup policy`. The finding highlights file systems where backups are not enabled or are being disabled.", + "Risk": "Absence of EFS backups degrades **availability** and **integrity**. Accidental deletion, ransomware, or misconfiguration can wipe or corrupt data with no recovery path. Without point-in-time copies, RPO/RTO suffer and localized incidents can become prolonged outages and irreversible loss.", "RelatedUrl": "", + "AdditionalURLs": [ + "https://docs.aws.amazon.com/efs/latest/ug/awsbackup.html", + "https://docs.aws.amazon.com/efs/latest/ug/automatic-backups.html" + ], "Remediation": { "Code": { - "CLI": "", - "NativeIaC": "", - "Other": "", - "Terraform": "" + "CLI": "aws efs put-backup-policy --file-system-id --backup-policy Status=ENABLED", + "NativeIaC": "```yaml\n# CloudFormation: Enable automatic backups for EFS\nResources:\n :\n Type: AWS::EFS::FileSystem\n Properties:\n BackupPolicy:\n Status: ENABLED # Critical: turns on EFS automatic backups via AWS Backup\n```", + "Other": "1. In the AWS Console, go to Amazon EFS > File systems\n2. Select the target file system\n3. Click Edit (or Update)\n4. Set Automatic backups to Enabled\n5. Save changes", + "Terraform": "```hcl\n# Enable automatic backups for EFS\nresource \"aws_efs_file_system\" \"\" {\n backup_policy {\n status = \"ENABLED\" # Critical: turns on EFS automatic backups\n }\n}\n```" }, "Recommendation": { - "Text": "Enable automated backup for production data. Define a retention period and periodically test backup restoration. A Disaster Recovery process should be in place to govern Data Protection approach.", - "Url": "https://docs.aws.amazon.com/efs/latest/ug/whatisefs.html" + "Text": "Enable automated EFS backups by setting the file system `backup policy` to `ENABLED` and applying defense-in-depth:\n- Schedule frequent jobs with tiered retention\n- Use immutable vaults and cross-Region copies\n- Restrict delete/restore via **least privilege** and **separation of duties**\n- Regularly test restores and document DR objectives", + "Url": "https://hub.prowler.com/check/efs_have_backup_enabled" } }, - "Categories": [], + "Categories": [ + "resilience" + ], "DependsOn": [], "RelatedTo": [], "Notes": "" diff --git a/prowler/providers/aws/services/efs/efs_mount_target_not_publicly_accessible/efs_mount_target_not_publicly_accessible.metadata.json b/prowler/providers/aws/services/efs/efs_mount_target_not_publicly_accessible/efs_mount_target_not_publicly_accessible.metadata.json index 99dc4ae0d6..6fbbd6c42f 100644 --- a/prowler/providers/aws/services/efs/efs_mount_target_not_publicly_accessible/efs_mount_target_not_publicly_accessible.metadata.json +++ b/prowler/providers/aws/services/efs/efs_mount_target_not_publicly_accessible/efs_mount_target_not_publicly_accessible.metadata.json @@ -1,28 +1,34 @@ { "Provider": "aws", "CheckID": "efs_mount_target_not_publicly_accessible", - "CheckTitle": "EFS mount targets should not be publicly accessible", + "CheckTitle": "EFS file system has no publicly accessible mount targets", "CheckType": [ - "Software and Configuration Checks/AWS Security Best Practices" + "Software and Configuration Checks/AWS Security Best Practices/Network Reachability", + "TTPs/Initial Access", + "Effects/Data Exposure" ], "ServiceName": "efs", "SubServiceName": "", - "ResourceIdTemplate": "arn:aws:elasticfilesystem:{region}:{account-id}:file-system/{filesystem-id}", + "ResourceIdTemplate": "", "Severity": "medium", "ResourceType": "AwsEfsFileSystem", - "Description": "This control checks whether an Amazon EFS mount target is associated with a public subnet since it can be accessed from the internet.", - "Risk": "Mount targets in public subnets may expose your EFS to unauthorized access or attacks.", - "RelatedUrl": "https://docs.aws.amazon.com/config/latest/developerguide/efs-mount-target-public-accessible.html", + "Description": "**EFS mount targets** associated with VPC subnets that auto-assign public IPv4 addresses (`mapPublicIpOnLaunch=true`) are identified per file system.\n\nThe evaluation focuses on the subnet attribute linked to each mount target.", + "Risk": "Publicly addressable mount targets expose NFS to Internet scanning and exploit attempts.\n- **Confidentiality**: unauthorized reads\n- **Integrity**: illicit writes or deletion\n- **Availability**: DDoS/resource exhaustion\n\n*Even with tight rules*, a public IP weakens isolation and eases recon.", + "RelatedUrl": "", + "AdditionalURLs": [ + "https://docs.aws.amazon.com/securityhub/latest/userguide/efs-controls.html#efs-6", + "https://docs.aws.amazon.com/efs/latest/ug/accessing-fs.html" + ], "Remediation": { "Code": { - "CLI": "aws efs create-mount-target --file-system-id --subnet-id --security-groups ", - "NativeIaC": "", - "Other": "https://docs.aws.amazon.com/securityhub/latest/userguide/efs-controls.html#efs-6", - "Terraform": "" + "CLI": "", + "NativeIaC": "```yaml\n# Create an EFS mount target in a private subnet\nResources:\n :\n Type: AWS::EFS::MountTarget\n Properties:\n FileSystemId: \n SubnetId: # FIX: Use a private subnet (no route to an Internet Gateway)\n SecurityGroups:\n - # Required SG for the mount target\n```", + "Other": "1. Open the AWS Console > EFS > File systems > select your file system\n2. Go to Networking and click Create mount target\n3. Choose a subnet that is private (no route to an Internet Gateway) and select a security group\n4. Click Create\n5. In Networking, select any mount targets in public subnets and click Delete to remove them", + "Terraform": "```hcl\n# Create an EFS mount target in a private subnet\nresource \"aws_efs_mount_target\" \"\" {\n file_system_id = \"\"\n subnet_id = \"\" # FIX: Use a private subnet (no route to an Internet Gateway)\n security_groups = [\"\"]\n}\n```" }, "Recommendation": { - "Text": "Recreate the EFS mount target in a private subnet to ensure it is not publicly accessible.", - "Url": "https://docs.aws.amazon.com/efs/latest/ug/accessing-fs.html" + "Text": "Place mount targets in **private subnets** that do not auto-assign public IPs (`mapPublicIpOnLaunch=false`). Apply **least privilege**: restrict NFS via security groups to known sources, avoid Internet routes, and use **defense in depth** with NACLs. Prefer private connectivity (VPN/Direct Connect or peering) for access.", + "Url": "https://hub.prowler.com/check/efs_mount_target_not_publicly_accessible" } }, "Categories": [ diff --git a/prowler/providers/aws/services/efs/efs_multi_az_enabled/efs_multi_az_enabled.metadata.json b/prowler/providers/aws/services/efs/efs_multi_az_enabled/efs_multi_az_enabled.metadata.json index 268678bc26..d970ce6ef3 100644 --- a/prowler/providers/aws/services/efs/efs_multi_az_enabled/efs_multi_az_enabled.metadata.json +++ b/prowler/providers/aws/services/efs/efs_multi_az_enabled/efs_multi_az_enabled.metadata.json @@ -1,30 +1,38 @@ { "Provider": "aws", "CheckID": "efs_multi_az_enabled", - "CheckTitle": "Check if EFS File systems are configured with Multi-AZ.", - "CheckType": [], + "CheckTitle": "EFS file system is Multi-AZ with more than one mount target", + "CheckType": [ + "Software and Configuration Checks/AWS Security Best Practices", + "Effects/Denial of Service" + ], "ServiceName": "efs", "SubServiceName": "", - "ResourceIdTemplate": "arn:partition:service:region:account-id:resource-id", + "ResourceIdTemplate": "", "Severity": "medium", "ResourceType": "AwsEfsFileSystem", - "Description": "Check if EFS File systems has Multi-AZ enabled.", - "Risk": "Ensure that your Amazon EFS are using Multi-AZ deployment configurations to provide High Availability (HA).", - "RelatedUrl": "https://docs.aws.amazon.com/efs/latest/ug/creating-using-create-fs.html#availabiltydurability", + "Description": "**Amazon EFS** file systems are assessed for **multi-AZ resilience**: Regional type (no `availability_zone_id`) with mount targets in more than one Availability Zone. Single-AZ (One Zone) or Regional with only one mount target is identified for attention.", + "Risk": "Concentrating access through a single AZ or a lone mount target reduces **availability**. An AZ outage can sever client connectivity, causing downtime and I/O errors. A single mount target also forces cross-AZ traffic, increasing latency and costs and undermining **resilience** and seamless failover.", + "RelatedUrl": "", + "AdditionalURLs": [ + "https://docs.aws.amazon.com/efs/latest/ug/creating-using-create-fs.html#availabiltydurability", + "https://docs.aws.amazon.com/efs/latest/ug/accessing-fs.html", + "https://ops.tips/gists/how-aws-efs-multiple-availability-zones-terraform/" + ], "Remediation": { "Code": { - "CLI": "", - "NativeIaC": "", - "Other": "", - "Terraform": "" + "CLI": "aws efs create-mount-target --file-system-id --subnet-id ", + "NativeIaC": "```yaml\n# CloudFormation: add an extra EFS mount target to another AZ\nResources:\n :\n Type: AWS::EFS::MountTarget\n Properties:\n FileSystemId: fs- # FIX: adds another mount target for this EFS\n SubnetId: subnet- # FIX: choose a subnet in a different AZ\n SecurityGroups:\n - # Required by CFN\n```", + "Other": "1. In AWS Console, go to EFS > File systems > select your file system\n2. If File system type shows Regional: open the Network tab > Mount targets > Manage mount targets > Add mount target\n3. Select a subnet in a different Availability Zone and save\n4. If File system type shows One Zone: create a new EFS with File system type = Regional and create mount targets in at least two AZs; remount clients to the new file system and decommission the old one", + "Terraform": "```hcl\n# Add an extra EFS mount target in a different AZ/subnet\nresource \"aws_efs_mount_target\" \"\" {\n file_system_id = \"\" # FIX: target EFS\n subnet_id = \"\" # FIX: subnet in another AZ to make targets > 1\n}\n```" }, "Recommendation": { - "Text": "Enable EFS file systems Multi-AZ with mount targets in multiple AZs.", - "Url": "https://docs.aws.amazon.com/efs/latest/ug/creating-using-create-fs.html#availabiltydurability" + "Text": "Use **Regional EFS** and create mount targets in each required **Availability Zone** to remove single points of failure and keep clients local to their AZ. Avoid One Zone for critical data. Periodically review mount target distribution to uphold **high availability** and **fault tolerance**.", + "Url": "https://hub.prowler.com/check/efs_multi_az_enabled" } }, "Categories": [ - "redundancy" + "resilience" ], "DependsOn": [], "RelatedTo": [], diff --git a/prowler/providers/aws/services/efs/efs_not_publicly_accessible/efs_not_publicly_accessible.metadata.json b/prowler/providers/aws/services/efs/efs_not_publicly_accessible/efs_not_publicly_accessible.metadata.json index d9ff105e93..0317066085 100644 --- a/prowler/providers/aws/services/efs/efs_not_publicly_accessible/efs_not_publicly_accessible.metadata.json +++ b/prowler/providers/aws/services/efs/efs_not_publicly_accessible/efs_not_publicly_accessible.metadata.json @@ -1,33 +1,37 @@ { "Provider": "aws", "CheckID": "efs_not_publicly_accessible", - "CheckTitle": "Check if EFS have policies which allow access to any client within the VPC", + "CheckTitle": "EFS file system policy does not allow access to any client within the VPC", "CheckType": [ - "Protect", - "Data protection" + "Software and Configuration Checks/AWS Security Best Practices/Network Reachability", + "Effects/Data Exposure" ], "ServiceName": "efs", "SubServiceName": "", - "ResourceIdTemplate": "arn:partition:service:region:account-id:resource-id", + "ResourceIdTemplate": "", "Severity": "medium", "ResourceType": "AwsEfsFileSystem", - "Description": "Check if EFS have policies which allow access to any client within the VPC", - "Risk": "Restricting access to EFS file systems is a security best practice. Allowing access to any client within the VPC can lead to unauthorized access to the file system.", + "Description": "**Amazon EFS** file system policy is assessed for **public or VPC-wide access**. Policies with broad `Principal` values or that permit any client in the VPC without the `elasticfilesystem:AccessedViaMountTarget` condition are identified.\n\n*An absent or empty policy is treated as open to VPC clients.*", + "Risk": "Broad EFS access lets any VPC client-or a compromised workload-mount the share, impacting CIA:\n- Confidentiality: bulk data exfiltration\n- Integrity: unauthorized writes or ransomware\n- Availability: deletion or lockout via elevated client access\nAlso facilitates lateral movement within the VPC.", "RelatedUrl": "", + "AdditionalURLs": [ + "https://docs.aws.amazon.com/efs/latest/ug/access-control-block-public-access.html", + "https://support.icompaas.com/support/solutions/articles/62000233324-efs-should-not-have-policies-allowing-unrestricted-access-within-vpc" + ], "Remediation": { "Code": { - "CLI": "", - "NativeIaC": "", - "Other": "", - "Terraform": "" + "CLI": "aws efs put-file-system-policy --file-system-id --policy '{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Principal\":\"*\",\"Action\":\"elasticfilesystem:ClientMount\",\"Condition\":{\"Bool\":{\"elasticfilesystem:AccessedViaMountTarget\":\"true\"}}}]}'", + "NativeIaC": "```yaml\n# CloudFormation: attach a non-public EFS file system policy\nResources:\n EFSFileSystemPolicy:\n Type: AWS::EFS::FileSystemPolicy\n Properties:\n FileSystemId: \n Policy:\n Version: \"2012-10-17\"\n Statement:\n - Effect: Allow\n Principal: \"*\"\n Action: elasticfilesystem:ClientMount\n Condition:\n Bool:\n elasticfilesystem:AccessedViaMountTarget: \"true\" # Critical: restrict access to mount targets only to avoid public access\n```", + "Other": "1. In the AWS Console, go to EFS > File systems and select \n2. Open the File system policy tab and click Edit\n3. Replace the policy with one that requires access via mount targets only:\n ```json\n {\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Effect\": \"Allow\",\n \"Principal\": \"*\",\n \"Action\": \"elasticfilesystem:ClientMount\",\n \"Condition\": {\"Bool\": {\"elasticfilesystem:AccessedViaMountTarget\": \"true\"}}\n }\n ]\n }\n ```\n4. Save changes", + "Terraform": "```hcl\n# Attach a non-public EFS file system policy\nresource \"aws_efs_file_system_policy\" \"\" {\n file_system_id = \"\"\n policy = jsonencode({\n Version = \"2012-10-17\"\n Statement = [{\n Effect = \"Allow\"\n Principal = \"*\"\n Action = \"elasticfilesystem:ClientMount\"\n Condition = {\n Bool = {\n \"elasticfilesystem:AccessedViaMountTarget\" = \"true\" # Critical: require mount target to make policy non-public\n }\n }\n }]\n })\n}\n```" }, "Recommendation": { - "Text": "Ensure efs has some policy but it does not have principle as *", - "Url": "https://docs.aws.amazon.com/efs/latest/ug/access-control-block-public-access.html" + "Text": "Apply **least privilege** to EFS resource policies:\n- Avoid wildcard `Principal` or `*`\n- Require `elasticfilesystem:AccessedViaMountTarget=true`\n- Constrain with `aws:SourceVpc`, `aws:SourceAccount`, or org IDs\n- Use EFS access points per app/role\n- Enable EFS **Block Public Access** for defense in depth", + "Url": "https://hub.prowler.com/check/efs_not_publicly_accessible" } }, "Categories": [ - "internet-exposed" + "identity-access" ], "DependsOn": [], "RelatedTo": [], diff --git a/prowler/providers/gcp/services/compute/compute_project_os_login_enabled/compute_project_os_login_enabled.py b/prowler/providers/gcp/services/compute/compute_project_os_login_enabled/compute_project_os_login_enabled.py index 4ed96e036e..5335379458 100644 --- a/prowler/providers/gcp/services/compute/compute_project_os_login_enabled/compute_project_os_login_enabled.py +++ b/prowler/providers/gcp/services/compute/compute_project_os_login_enabled/compute_project_os_login_enabled.py @@ -11,6 +11,11 @@ class compute_project_os_login_enabled(Check): resource=compute_client.projects[project.id], project_id=project.id, location=compute_client.region, + resource_name=( + compute_client.projects[project.id].name + if compute_client.projects[project.id].name + else "GCP Project" + ), ) report.status = "PASS" report.status_extended = f"Project {project.id} has OS Login enabled." diff --git a/prowler/providers/gcp/services/iam/iam_audit_logs_enabled/iam_audit_logs_enabled.py b/prowler/providers/gcp/services/iam/iam_audit_logs_enabled/iam_audit_logs_enabled.py index bec0cb851f..1f3e1bb993 100644 --- a/prowler/providers/gcp/services/iam/iam_audit_logs_enabled/iam_audit_logs_enabled.py +++ b/prowler/providers/gcp/services/iam/iam_audit_logs_enabled/iam_audit_logs_enabled.py @@ -13,6 +13,11 @@ class iam_audit_logs_enabled(Check): resource=cloudresourcemanager_client.projects[project.id], project_id=project.id, location=cloudresourcemanager_client.region, + resource_name=( + cloudresourcemanager_client.projects[project.id].name + if cloudresourcemanager_client.projects[project.id].name + else "GCP Project" + ), ) report.status = "PASS" report.status_extended = f"Audit Logs are enabled for project {project.id}." diff --git a/prowler/providers/gcp/services/iam/iam_role_kms_enforce_separation_of_duties/iam_role_kms_enforce_separation_of_duties.py b/prowler/providers/gcp/services/iam/iam_role_kms_enforce_separation_of_duties/iam_role_kms_enforce_separation_of_duties.py index 7450b4b933..b2772b2d0c 100644 --- a/prowler/providers/gcp/services/iam/iam_role_kms_enforce_separation_of_duties/iam_role_kms_enforce_separation_of_duties.py +++ b/prowler/providers/gcp/services/iam/iam_role_kms_enforce_separation_of_duties/iam_role_kms_enforce_separation_of_duties.py @@ -15,6 +15,11 @@ class iam_role_kms_enforce_separation_of_duties(Check): resource=cloudresourcemanager_client.projects[project], project_id=project, location=cloudresourcemanager_client.region, + resource_name=( + cloudresourcemanager_client.projects[project].name + if cloudresourcemanager_client.projects[project].name + else "GCP Project" + ), ) report.status = "PASS" report.status_extended = f"Principle of separation of duties was enforced for KMS-Related Roles in project {project}." diff --git a/prowler/providers/gcp/services/logging/logging_log_metric_filter_and_alert_for_audit_configuration_changes_enabled/logging_log_metric_filter_and_alert_for_audit_configuration_changes_enabled.py b/prowler/providers/gcp/services/logging/logging_log_metric_filter_and_alert_for_audit_configuration_changes_enabled/logging_log_metric_filter_and_alert_for_audit_configuration_changes_enabled.py index fd48f9dd4b..4654be4d29 100644 --- a/prowler/providers/gcp/services/logging/logging_log_metric_filter_and_alert_for_audit_configuration_changes_enabled/logging_log_metric_filter_and_alert_for_audit_configuration_changes_enabled.py +++ b/prowler/providers/gcp/services/logging/logging_log_metric_filter_and_alert_for_audit_configuration_changes_enabled/logging_log_metric_filter_and_alert_for_audit_configuration_changes_enabled.py @@ -40,6 +40,11 @@ class logging_log_metric_filter_and_alert_for_audit_configuration_changes_enable resource=logging_client.projects[project], project_id=project, location=logging_client.region, + resource_name=( + logging_client.projects[project].name + if logging_client.projects[project].name + else "GCP Project" + ), ) report.status = "FAIL" report.status_extended = f"There are no log metric filters or alerts associated in project {project}." diff --git a/prowler/providers/gcp/services/logging/logging_log_metric_filter_and_alert_for_bucket_permission_changes_enabled/logging_log_metric_filter_and_alert_for_bucket_permission_changes_enabled.py b/prowler/providers/gcp/services/logging/logging_log_metric_filter_and_alert_for_bucket_permission_changes_enabled/logging_log_metric_filter_and_alert_for_bucket_permission_changes_enabled.py index db9ea7e95e..c6cca1fab2 100644 --- a/prowler/providers/gcp/services/logging/logging_log_metric_filter_and_alert_for_bucket_permission_changes_enabled/logging_log_metric_filter_and_alert_for_bucket_permission_changes_enabled.py +++ b/prowler/providers/gcp/services/logging/logging_log_metric_filter_and_alert_for_bucket_permission_changes_enabled/logging_log_metric_filter_and_alert_for_bucket_permission_changes_enabled.py @@ -38,6 +38,11 @@ class logging_log_metric_filter_and_alert_for_bucket_permission_changes_enabled( resource=logging_client.projects[project], project_id=project, location=logging_client.region, + resource_name=( + logging_client.projects[project].name + if logging_client.projects[project].name + else "GCP Project" + ), ) report.status = "FAIL" report.status_extended = f"There are no log metric filters or alerts associated in project {project}." diff --git a/prowler/providers/gcp/services/logging/logging_log_metric_filter_and_alert_for_custom_role_changes_enabled/logging_log_metric_filter_and_alert_for_custom_role_changes_enabled.py b/prowler/providers/gcp/services/logging/logging_log_metric_filter_and_alert_for_custom_role_changes_enabled/logging_log_metric_filter_and_alert_for_custom_role_changes_enabled.py index 13a2d45737..1e6584e5fb 100644 --- a/prowler/providers/gcp/services/logging/logging_log_metric_filter_and_alert_for_custom_role_changes_enabled/logging_log_metric_filter_and_alert_for_custom_role_changes_enabled.py +++ b/prowler/providers/gcp/services/logging/logging_log_metric_filter_and_alert_for_custom_role_changes_enabled/logging_log_metric_filter_and_alert_for_custom_role_changes_enabled.py @@ -38,6 +38,11 @@ class logging_log_metric_filter_and_alert_for_custom_role_changes_enabled(Check) resource=logging_client.projects[project], project_id=project, location=logging_client.region, + resource_name=( + logging_client.projects[project].name + if logging_client.projects[project].name + else "GCP Project" + ), ) report.status = "FAIL" report.status_extended = f"There are no log metric filters or alerts associated in project {project}." diff --git a/prowler/providers/gcp/services/logging/logging_log_metric_filter_and_alert_for_project_ownership_changes_enabled/logging_log_metric_filter_and_alert_for_project_ownership_changes_enabled.py b/prowler/providers/gcp/services/logging/logging_log_metric_filter_and_alert_for_project_ownership_changes_enabled/logging_log_metric_filter_and_alert_for_project_ownership_changes_enabled.py index e56feb3318..9f3cb38d29 100644 --- a/prowler/providers/gcp/services/logging/logging_log_metric_filter_and_alert_for_project_ownership_changes_enabled/logging_log_metric_filter_and_alert_for_project_ownership_changes_enabled.py +++ b/prowler/providers/gcp/services/logging/logging_log_metric_filter_and_alert_for_project_ownership_changes_enabled/logging_log_metric_filter_and_alert_for_project_ownership_changes_enabled.py @@ -38,6 +38,11 @@ class logging_log_metric_filter_and_alert_for_project_ownership_changes_enabled( resource=logging_client.projects[project], project_id=project, location=logging_client.region, + resource_name=( + logging_client.projects[project].name + if logging_client.projects[project].name + else "GCP Project" + ), ) report.status = "FAIL" report.status_extended = f"There are no log metric filters or alerts associated in project {project}." diff --git a/prowler/providers/gcp/services/logging/logging_log_metric_filter_and_alert_for_sql_instance_configuration_changes_enabled/logging_log_metric_filter_and_alert_for_sql_instance_configuration_changes_enabled.py b/prowler/providers/gcp/services/logging/logging_log_metric_filter_and_alert_for_sql_instance_configuration_changes_enabled/logging_log_metric_filter_and_alert_for_sql_instance_configuration_changes_enabled.py index 5e37003409..3e499db10a 100644 --- a/prowler/providers/gcp/services/logging/logging_log_metric_filter_and_alert_for_sql_instance_configuration_changes_enabled/logging_log_metric_filter_and_alert_for_sql_instance_configuration_changes_enabled.py +++ b/prowler/providers/gcp/services/logging/logging_log_metric_filter_and_alert_for_sql_instance_configuration_changes_enabled/logging_log_metric_filter_and_alert_for_sql_instance_configuration_changes_enabled.py @@ -37,6 +37,11 @@ class logging_log_metric_filter_and_alert_for_sql_instance_configuration_changes resource=logging_client.projects[project], project_id=project, location=logging_client.region, + resource_name=( + logging_client.projects[project].name + if logging_client.projects[project].name + else "GCP Project" + ), ) report.status = "FAIL" report.status_extended = f"There are no log metric filters or alerts associated in project {project}." diff --git a/prowler/providers/gcp/services/logging/logging_log_metric_filter_and_alert_for_vpc_firewall_rule_changes_enabled/logging_log_metric_filter_and_alert_for_vpc_firewall_rule_changes_enabled.py b/prowler/providers/gcp/services/logging/logging_log_metric_filter_and_alert_for_vpc_firewall_rule_changes_enabled/logging_log_metric_filter_and_alert_for_vpc_firewall_rule_changes_enabled.py index 754f651d4d..e2b7cdcc13 100644 --- a/prowler/providers/gcp/services/logging/logging_log_metric_filter_and_alert_for_vpc_firewall_rule_changes_enabled/logging_log_metric_filter_and_alert_for_vpc_firewall_rule_changes_enabled.py +++ b/prowler/providers/gcp/services/logging/logging_log_metric_filter_and_alert_for_vpc_firewall_rule_changes_enabled/logging_log_metric_filter_and_alert_for_vpc_firewall_rule_changes_enabled.py @@ -38,6 +38,11 @@ class logging_log_metric_filter_and_alert_for_vpc_firewall_rule_changes_enabled( resource=logging_client.projects[project], project_id=project, location=logging_client.region, + resource_name=( + logging_client.projects[project].name + if logging_client.projects[project].name + else "GCP Project" + ), ) report.status = "FAIL" report.status_extended = f"There are no log metric filters or alerts associated in project {project}." diff --git a/prowler/providers/gcp/services/logging/logging_log_metric_filter_and_alert_for_vpc_network_changes_enabled/logging_log_metric_filter_and_alert_for_vpc_network_changes_enabled.py b/prowler/providers/gcp/services/logging/logging_log_metric_filter_and_alert_for_vpc_network_changes_enabled/logging_log_metric_filter_and_alert_for_vpc_network_changes_enabled.py index 5073b59879..c8b15ce1ee 100644 --- a/prowler/providers/gcp/services/logging/logging_log_metric_filter_and_alert_for_vpc_network_changes_enabled/logging_log_metric_filter_and_alert_for_vpc_network_changes_enabled.py +++ b/prowler/providers/gcp/services/logging/logging_log_metric_filter_and_alert_for_vpc_network_changes_enabled/logging_log_metric_filter_and_alert_for_vpc_network_changes_enabled.py @@ -38,6 +38,11 @@ class logging_log_metric_filter_and_alert_for_vpc_network_changes_enabled(Check) resource=logging_client.projects[project], project_id=project, location=logging_client.region, + resource_name=( + logging_client.projects[project].name + if logging_client.projects[project].name + else "GCP Project" + ), ) report.status = "FAIL" report.status_extended = f"There are no log metric filters or alerts associated in project {project}." diff --git a/prowler/providers/gcp/services/logging/logging_log_metric_filter_and_alert_for_vpc_network_route_changes_enabled/logging_log_metric_filter_and_alert_for_vpc_network_route_changes_enabled.py b/prowler/providers/gcp/services/logging/logging_log_metric_filter_and_alert_for_vpc_network_route_changes_enabled/logging_log_metric_filter_and_alert_for_vpc_network_route_changes_enabled.py index 9b78bc314a..f840d75852 100644 --- a/prowler/providers/gcp/services/logging/logging_log_metric_filter_and_alert_for_vpc_network_route_changes_enabled/logging_log_metric_filter_and_alert_for_vpc_network_route_changes_enabled.py +++ b/prowler/providers/gcp/services/logging/logging_log_metric_filter_and_alert_for_vpc_network_route_changes_enabled/logging_log_metric_filter_and_alert_for_vpc_network_route_changes_enabled.py @@ -38,6 +38,11 @@ class logging_log_metric_filter_and_alert_for_vpc_network_route_changes_enabled( resource=logging_client.projects[project], project_id=project, location=logging_client.region, + resource_name=( + logging_client.projects[project].name + if logging_client.projects[project].name + else "GCP Project" + ), ) report.status = "FAIL" report.status_extended = f"There are no log metric filters or alerts associated in project {project}." diff --git a/prowler/providers/gcp/services/logging/logging_sink_created/logging_sink_created.py b/prowler/providers/gcp/services/logging/logging_sink_created/logging_sink_created.py index a72d45e07e..e57ff0e671 100644 --- a/prowler/providers/gcp/services/logging/logging_sink_created/logging_sink_created.py +++ b/prowler/providers/gcp/services/logging/logging_sink_created/logging_sink_created.py @@ -17,6 +17,11 @@ class logging_sink_created(Check): resource=logging_client.projects[project], project_id=project, location=logging_client.region, + resource_name=( + logging_client.projects[project].name + if logging_client.projects[project].name + else "GCP Project" + ), ) report.status = "FAIL" report.status_extended = f"There are no logging sinks to export copies of all the log entries in project {project}." diff --git a/pyproject.toml b/pyproject.toml index 9c626c3153..7b7934011c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -116,15 +116,6 @@ pytest-xdist = "3.6.1" safety = "3.2.9" vulture = "2.14" -[tool.poetry.group.docs] -optional = true - -[tool.poetry.group.docs.dependencies] -mkdocs = "1.6.1" -mkdocs-git-revision-date-localized-plugin = "1.4.1" -mkdocs-material = "9.6.5" -mkdocs-material-extensions = "1.3.1" - [tool.poetry-version-plugin] source = "init" diff --git a/ui/.gitignore b/ui/.gitignore index 555ceeb8d3..3b905e64d8 100644 --- a/ui/.gitignore +++ b/ui/.gitignore @@ -33,4 +33,5 @@ yarn-error.log* # typescript *.tsbuildinfo -next-env.d.ts \ No newline at end of file +next-env.d.ts +playwright/.auth diff --git a/ui/CHANGELOG.md b/ui/CHANGELOG.md index 2ef5f2d74d..9f0174f4ba 100644 --- a/ui/CHANGELOG.md +++ b/ui/CHANGELOG.md @@ -16,6 +16,7 @@ All notable changes to the **Prowler UI** are documented in this file. - API key management in user profile [(#8308)](https://github.com/prowler-cloud/prowler/pull/8308) - Refresh access token error handling [(#8864)](https://github.com/prowler-cloud/prowler/pull/8864) - Support Common Cloud Controls for AWS, Azure and GCP [(#8000)](https://github.com/prowler-cloud/prowler/pull/8000) +- New M365 credentials certificate authentication method [(#8929)](https://github.com/prowler-cloud/prowler/pull/8929) ### 🔄 Changed @@ -36,6 +37,7 @@ All notable changes to the **Prowler UI** are documented in this file. - ThreatScore for each pillar in Prowler ThreatScore specific view [(#8582)](https://github.com/prowler-cloud/prowler/pull/8582) - Remove maxTokens model param for GPT-5 models [(#8843)](https://github.com/prowler-cloud/prowler/pull/8843) - MITRE ATTACK compliance view now shows all requirements in charts [(#8886)](https://github.com/prowler-cloud/prowler/pull/8886) +- Mutelist menu item now doesn't blink [(#8932)](https://github.com/prowler-cloud/prowler/pull/8932) --- diff --git a/ui/app/(prowler)/providers/(set-up-provider)/add-credentials/page.tsx b/ui/app/(prowler)/providers/(set-up-provider)/add-credentials/page.tsx index 1c039886b9..3490cdb792 100644 --- a/ui/app/(prowler)/providers/(set-up-provider)/add-credentials/page.tsx +++ b/ui/app/(prowler)/providers/(set-up-provider)/add-credentials/page.tsx @@ -10,6 +10,7 @@ import { SelectViaGCP, } from "@/components/providers/workflow/forms/select-credentials-type/gcp"; import { SelectViaGitHub } from "@/components/providers/workflow/forms/select-credentials-type/github"; +import { SelectViaM365 } from "@/components/providers/workflow/forms/select-credentials-type/m365"; import { getProviderFormType } from "@/lib/provider-helpers"; import { ProviderType } from "@/types/providers"; @@ -28,6 +29,7 @@ export default async function AddCredentialsPage({ searchParams }: Props) { if (providerType === "gcp") return ; if (providerType === "github") return ; + if (providerType === "m365") return ; return null; case "credentials": diff --git a/ui/app/(prowler)/providers/page.tsx b/ui/app/(prowler)/providers/page.tsx index 6d3ca01338..e6726c2fd5 100644 --- a/ui/app/(prowler)/providers/page.tsx +++ b/ui/app/(prowler)/providers/page.tsx @@ -28,31 +28,36 @@ export default async function Providers({ - -
- - - -
- -
-
- -
-
- - } - > - + + + }> +
); } -const ProvidersContent = async ({ +const ProvidersActions = () => { + return ( +
+ + + +
+ ); +}; + +const ProvidersTableFallback = () => { + return ( +
+
+ +
+
+ ); +}; + +const ProvidersTable = async ({ searchParams, }: { searchParams: SearchParamsProps; @@ -97,13 +102,6 @@ const ProvidersContent = async ({ return ( <> -
- - - -
- -
; } + if (providerType === "m365") { + return ; + } return null; }; diff --git a/ui/components/providers/muted-findings-config-button.tsx b/ui/components/providers/muted-findings-config-button.tsx index 645b6e6584..c560222f2d 100644 --- a/ui/components/providers/muted-findings-config-button.tsx +++ b/ui/components/providers/muted-findings-config-button.tsx @@ -1,6 +1,8 @@ "use client"; import { SettingsIcon } from "lucide-react"; +import { usePathname } from "next/navigation"; +import { useEffect } from "react"; import { CustomAlertModal, CustomButton } from "@/components/ui/custom"; import { useUIStore } from "@/store/ui/store"; @@ -8,13 +10,38 @@ import { useUIStore } from "@/store/ui/store"; import { MutedFindingsConfigForm } from "./forms"; export const MutedFindingsConfigButton = () => { + const pathname = usePathname(); const { isMutelistModalOpen, openMutelistModal, closeMutelistModal, hasProviders, + shouldAutoOpenMutelist, + resetMutelistModalRequest, } = useUIStore(); + useEffect(() => { + if (!shouldAutoOpenMutelist) { + return; + } + + if (pathname !== "/providers") { + return; + } + + if (hasProviders) { + openMutelistModal(); + } + + resetMutelistModalRequest(); + }, [ + hasProviders, + openMutelistModal, + pathname, + resetMutelistModalRequest, + shouldAutoOpenMutelist, + ]); + const handleOpenModal = () => { if (hasProviders) { openMutelistModal(); diff --git a/ui/components/providers/workflow/forms/base-credentials-form.tsx b/ui/components/providers/workflow/forms/base-credentials-form.tsx index 9c66103e1d..a50cfdeb74 100644 --- a/ui/components/providers/workflow/forms/base-credentials-form.tsx +++ b/ui/components/providers/workflow/forms/base-credentials-form.tsx @@ -17,7 +17,8 @@ import { GCPDefaultCredentials, GCPServiceAccountKey, KubernetesCredentials, - M365Credentials, + M365CertificateCredentials, + M365ClientSecretCredentials, ProviderType, } from "@/types"; @@ -26,10 +27,13 @@ import { AWSStaticCredentialsForm } from "./select-credentials-type/aws/credenti import { AWSRoleCredentialsForm } from "./select-credentials-type/aws/credentials-type/aws-role-credentials-form"; import { GCPDefaultCredentialsForm } from "./select-credentials-type/gcp/credentials-type"; import { GCPServiceAccountKeyForm } from "./select-credentials-type/gcp/credentials-type/gcp-service-account-key-form"; +import { + M365CertificateCredentialsForm, + M365ClientSecretCredentialsForm, +} from "./select-credentials-type/m365"; import { AzureCredentialsForm } from "./via-credentials/azure-credentials-form"; import { GitHubCredentialsForm } from "./via-credentials/github-credentials-form"; import { KubernetesCredentialsForm } from "./via-credentials/k8s-credentials-form"; -import { M365CredentialsForm } from "./via-credentials/m365-credentials-form"; type BaseCredentialsFormProps = { providerType: ProviderType; @@ -103,11 +107,22 @@ export const BaseCredentialsForm = ({ control={form.control as unknown as Control} /> )} - {providerType === "m365" && ( - } - /> - )} + {providerType === "m365" && + searchParamsObj.get("via") === "app_client_secret" && ( + + } + /> + )} + {providerType === "m365" && + searchParamsObj.get("via") === "app_certificate" && ( + + } + /> + )} {providerType === "gcp" && searchParamsObj.get("via") === "service-account" && ( } + onPress={(e) => { + const formElement = e.target as HTMLElement; + const form = formElement.closest("form"); + if (form) { + form.dispatchEvent( + new Event("submit", { bubbles: true, cancelable: true }), + ); + } + }} > {isLoading ? <>Loading : {submitButtonText}} diff --git a/ui/components/providers/workflow/forms/select-credentials-type/m365/credentials-type/index.ts b/ui/components/providers/workflow/forms/select-credentials-type/m365/credentials-type/index.ts new file mode 100644 index 0000000000..91d6766bac --- /dev/null +++ b/ui/components/providers/workflow/forms/select-credentials-type/m365/credentials-type/index.ts @@ -0,0 +1,2 @@ +export { M365CertificateCredentialsForm } from "./m365-certificate-credentials-form"; +export { M365ClientSecretCredentialsForm } from "./m365-client-secret-credentials-form"; diff --git a/ui/components/providers/workflow/forms/select-credentials-type/m365/credentials-type/m365-certificate-credentials-form.tsx b/ui/components/providers/workflow/forms/select-credentials-type/m365/credentials-type/m365-certificate-credentials-form.tsx new file mode 100644 index 0000000000..03dd5a72e0 --- /dev/null +++ b/ui/components/providers/workflow/forms/select-credentials-type/m365/credentials-type/m365-certificate-credentials-form.tsx @@ -0,0 +1,72 @@ +"use client"; + +import { Control } from "react-hook-form"; + +import { CustomInput, CustomTextarea } from "@/components/ui/custom"; +import { CustomLink } from "@/components/ui/custom/custom-link"; +import { M365CertificateCredentials } from "@/types"; + +export const M365CertificateCredentialsForm = ({ + control, +}: { + control: Control; +}) => { + return ( + <> +
+
+ App Certificate Credentials +
+
+ Please provide your Microsoft 365 application credentials with + certificate authentication. +
+
+ + + +

+ The certificate content must be base64 encoded from an unsigned + certificate. For detailed instructions on how to generate and encode + your certificate, please refer to the{" "} + + certificate generation guide + + . +

+ + ); +}; diff --git a/ui/components/providers/workflow/forms/select-credentials-type/m365/credentials-type/m365-client-secret-credentials-form.tsx b/ui/components/providers/workflow/forms/select-credentials-type/m365/credentials-type/m365-client-secret-credentials-form.tsx new file mode 100644 index 0000000000..3312fb536a --- /dev/null +++ b/ui/components/providers/workflow/forms/select-credentials-type/m365/credentials-type/m365-client-secret-credentials-form.tsx @@ -0,0 +1,58 @@ +"use client"; + +import { Control } from "react-hook-form"; + +import { CustomInput } from "@/components/ui/custom"; +import { M365ClientSecretCredentials } from "@/types"; + +export const M365ClientSecretCredentialsForm = ({ + control, +}: { + control: Control; +}) => { + return ( + <> +
+
+ App Client Secret Credentials +
+
+ Please provide your Microsoft 365 application credentials. +
+
+ + + + + ); +}; diff --git a/ui/components/providers/workflow/forms/select-credentials-type/m365/index.ts b/ui/components/providers/workflow/forms/select-credentials-type/m365/index.ts new file mode 100644 index 0000000000..84610f510a --- /dev/null +++ b/ui/components/providers/workflow/forms/select-credentials-type/m365/index.ts @@ -0,0 +1,5 @@ +export { + M365CertificateCredentialsForm, + M365ClientSecretCredentialsForm, +} from "./credentials-type"; +export { SelectViaM365 } from "./select-via-m365"; diff --git a/ui/components/providers/workflow/forms/select-credentials-type/m365/radio-group-m365-via-credentials-type-form.tsx b/ui/components/providers/workflow/forms/select-credentials-type/m365/radio-group-m365-via-credentials-type-form.tsx new file mode 100644 index 0000000000..2f5599363b --- /dev/null +++ b/ui/components/providers/workflow/forms/select-credentials-type/m365/radio-group-m365-via-credentials-type-form.tsx @@ -0,0 +1,72 @@ +"use client"; + +import { RadioGroup } from "@heroui/radio"; +import React from "react"; +import { Control, Controller } from "react-hook-form"; + +import { CustomRadio } from "@/components/ui/custom"; +import { FormMessage } from "@/components/ui/form"; + +type RadioGroupM365ViaCredentialsFormProps = { + control: Control; + isInvalid: boolean; + errorMessage?: string; + onChange?: (value: string) => void; +}; + +export const RadioGroupM365ViaCredentialsTypeForm = ({ + control, + isInvalid, + errorMessage, + onChange, +}: RadioGroupM365ViaCredentialsFormProps) => { + return ( + ( + <> + { + field.onChange(value); + if (onChange) { + onChange(value); + } + }} + > +
+ + Select Authentication Method + + +
+ App Client Secret Credentials +
+
+ +
+ App Certificate Credentials +
+
+
+
+ {errorMessage && ( + + {errorMessage} + + )} + + )} + /> + ); +}; diff --git a/ui/components/providers/workflow/forms/select-credentials-type/m365/select-via-m365.tsx b/ui/components/providers/workflow/forms/select-credentials-type/m365/select-via-m365.tsx new file mode 100644 index 0000000000..020e4ed0e1 --- /dev/null +++ b/ui/components/providers/workflow/forms/select-credentials-type/m365/select-via-m365.tsx @@ -0,0 +1,38 @@ +"use client"; + +import { useRouter } from "next/navigation"; +import { useForm } from "react-hook-form"; + +import { Form } from "@/components/ui/form"; + +import { RadioGroupM365ViaCredentialsTypeForm } from "./radio-group-m365-via-credentials-type-form"; + +interface SelectViaM365Props { + initialVia?: string; +} + +export const SelectViaM365 = ({ initialVia }: SelectViaM365Props) => { + const router = useRouter(); + const form = useForm({ + defaultValues: { + m365CredentialsType: initialVia || "", + }, + }); + + const handleSelectionChange = (value: string) => { + const url = new URL(window.location.href); + url.searchParams.set("via", value); + router.push(url.toString()); + }; + + return ( +
+ + + ); +}; diff --git a/ui/components/providers/workflow/forms/via-credentials/index.ts b/ui/components/providers/workflow/forms/via-credentials/index.ts index d020b9715f..982e5ca701 100644 --- a/ui/components/providers/workflow/forms/via-credentials/index.ts +++ b/ui/components/providers/workflow/forms/via-credentials/index.ts @@ -1,4 +1,3 @@ export * from "./azure-credentials-form"; export * from "./github-credentials-form"; export * from "./k8s-credentials-form"; -export * from "./m365-credentials-form"; diff --git a/ui/components/providers/workflow/forms/via-credentials/m365-credentials-form.tsx b/ui/components/providers/workflow/forms/via-credentials/m365-credentials-form.tsx deleted file mode 100644 index 1659a503e8..0000000000 --- a/ui/components/providers/workflow/forms/via-credentials/m365-credentials-form.tsx +++ /dev/null @@ -1,109 +0,0 @@ -import { Control } from "react-hook-form"; - -import { InfoIcon } from "@/components/icons"; -import { CustomInput } from "@/components/ui/custom"; -import { CustomLink } from "@/components/ui/custom/custom-link"; -import { M365Credentials } from "@/types"; - -export const M365CredentialsForm = ({ - control, -}: { - control: Control; -}) => { - return ( - <> -
-
- Connect via Credentials -
-
- Please provide the information for your Microsoft 365 credentials. -
-
- - - -

- {" "} - User and password authentication is being deprecated due to - Microsoft's on-going MFA enforcement across all tenants (see{" "} - - Microsoft docs - - ). -

- -
- -

- By October 2025, MFA will be mandatory. -

-
-

- Due to that change, you must only{" "} - - use application authentication - {" "} - to maintain all Prowler M365 scan capabilities. -

- - - - ); -}; diff --git a/ui/components/shadcn/README.md b/ui/components/shadcn/README.md new file mode 100644 index 0000000000..1bd28c8883 --- /dev/null +++ b/ui/components/shadcn/README.md @@ -0,0 +1,57 @@ +# shadcn Components + +This directory contains all shadcn/ui based components for the Prowler application. + +## Directory Structure + +``` +shadcn/ +├── card.tsx # shadcn Card component +├── resource-stats-card/ # Custom ResourceStatsCard built on shadcn +│ ├── resource-stats-card.tsx +│ ├── resource-stats-card.example.tsx +│ └── index.ts +├── index.ts # Barrel exports +└── README.md +``` + +## Usage + +All shadcn components can be imported from `@/components/shadcn`: + +```tsx +import { Card, CardHeader, CardContent } from "@/components/shadcn"; +import { ResourceStatsCard } from "@/components/shadcn"; +``` + +## Adding New shadcn Components + +When adding new shadcn components using the CLI: + +```bash +npx shadcn@latest add [component-name] +``` + +The component will be automatically added to this directory due to the configuration in `components.json`: + +```json +{ + "aliases": { + "ui": "@/components/shadcn" + } +} +``` + +## Component Guidelines + +1. **shadcn base components** - Use as-is from shadcn/ui (e.g., `card.tsx`) +2. **Custom components built on shadcn** - Create in subdirectories (e.g., `resource-stats-card/`) +3. **CVA variants** - Use Class Variance Authority for type-safe variants +4. **Theme support** - Include `dark:` classes for dark/light theme compatibility +5. **TypeScript** - Always export types and use proper typing + +## Resources + +- [shadcn/ui Documentation](https://ui.shadcn.com) +- [CVA Documentation](https://cva.style/docs) +- [Tailwind CSS Documentation](https://tailwindcss.com/docs) diff --git a/ui/components/shadcn/card.tsx b/ui/components/shadcn/card.tsx new file mode 100644 index 0000000000..a1b4a7742d --- /dev/null +++ b/ui/components/shadcn/card.tsx @@ -0,0 +1,92 @@ +import * as React from "react"; + +import { cn } from "@/lib/utils"; + +function Card({ className, ...props }: React.ComponentProps<"div">) { + return ( +
+ ); +} + +function CardHeader({ className, ...props }: React.ComponentProps<"div">) { + return ( +
+ ); +} + +function CardTitle({ className, ...props }: React.ComponentProps<"div">) { + return ( +
+ ); +} + +function CardDescription({ className, ...props }: React.ComponentProps<"div">) { + return ( +
+ ); +} + +function CardAction({ className, ...props }: React.ComponentProps<"div">) { + return ( +
+ ); +} + +function CardContent({ className, ...props }: React.ComponentProps<"div">) { + return ( +
+ ); +} + +function CardFooter({ className, ...props }: React.ComponentProps<"div">) { + return ( +
+ ); +} + +export { + Card, + CardAction, + CardContent, + CardDescription, + CardFooter, + CardHeader, + CardTitle, +}; diff --git a/ui/components/shadcn/index.ts b/ui/components/shadcn/index.ts new file mode 100644 index 0000000000..4291e07d5a --- /dev/null +++ b/ui/components/shadcn/index.ts @@ -0,0 +1,21 @@ +export { + Card, + CardContent, + CardDescription, + CardFooter, + CardHeader, + CardTitle, +} from "./card"; +export { + ResourceStatsCard, + ResourceStatsCardContainer, + type ResourceStatsCardContainerProps, + ResourceStatsCardContent, + type ResourceStatsCardContentProps, + ResourceStatsCardDivider, + type ResourceStatsCardDividerProps, + ResourceStatsCardHeader, + type ResourceStatsCardHeaderProps, + type ResourceStatsCardProps, + type StatItem, +} from "./resource-stats-card"; diff --git a/ui/components/shadcn/resource-stats-card/index.ts b/ui/components/shadcn/resource-stats-card/index.ts new file mode 100644 index 0000000000..c049987ae0 --- /dev/null +++ b/ui/components/shadcn/resource-stats-card/index.ts @@ -0,0 +1,13 @@ +export type { ResourceStatsCardProps } from "./resource-stats-card"; +export { ResourceStatsCard } from "./resource-stats-card"; +export type { ResourceStatsCardContainerProps } from "./resource-stats-card-container"; +export { ResourceStatsCardContainer } from "./resource-stats-card-container"; +export type { + ResourceStatsCardContentProps, + StatItem, +} from "./resource-stats-card-content"; +export { ResourceStatsCardContent } from "./resource-stats-card-content"; +export type { ResourceStatsCardDividerProps } from "./resource-stats-card-divider"; +export { ResourceStatsCardDivider } from "./resource-stats-card-divider"; +export type { ResourceStatsCardHeaderProps } from "./resource-stats-card-header"; +export { ResourceStatsCardHeader } from "./resource-stats-card-header"; diff --git a/ui/components/shadcn/resource-stats-card/resource-stats-card-container.tsx b/ui/components/shadcn/resource-stats-card/resource-stats-card-container.tsx new file mode 100644 index 0000000000..78dc88fb71 --- /dev/null +++ b/ui/components/shadcn/resource-stats-card/resource-stats-card-container.tsx @@ -0,0 +1,55 @@ +import { cva, type VariantProps } from "class-variance-authority"; + +import { cn } from "@/lib/utils"; + +const containerVariants = cva( + [ + "flex", + "rounded-[12px]", + "border", + "backdrop-blur-[46px]", + "border-[rgba(38,38,38,0.70)]", + "bg-[rgba(23,23,23,0.50)]", + "dark:border-[rgba(38,38,38,0.70)]", + "dark:bg-[rgba(23,23,23,0.50)]", + ], + { + variants: { + padding: { + sm: "px-3 py-2", + md: "px-[19px] py-[9px]", + lg: "px-6 py-3", + none: "p-0", + }, + }, + defaultVariants: { + padding: "md", + }, + }, +); + +export interface ResourceStatsCardContainerProps + extends React.HTMLAttributes, + VariantProps { + ref?: React.Ref; +} + +export const ResourceStatsCardContainer = ({ + className, + children, + padding, + ref, + ...props +}: ResourceStatsCardContainerProps) => { + return ( +
+ {children} +
+ ); +}; + +ResourceStatsCardContainer.displayName = "ResourceStatsCardContainer"; diff --git a/ui/components/shadcn/resource-stats-card/resource-stats-card-content.tsx b/ui/components/shadcn/resource-stats-card/resource-stats-card-content.tsx new file mode 100644 index 0000000000..d165eb7944 --- /dev/null +++ b/ui/components/shadcn/resource-stats-card/resource-stats-card-content.tsx @@ -0,0 +1,204 @@ +import { cva } from "class-variance-authority"; +import { LucideIcon } from "lucide-react"; + +import { cn } from "@/lib/utils"; + +export interface StatItem { + icon: LucideIcon; + label: string; +} + +export const CardVariant = { + default: "default", + fail: "fail", + pass: "pass", + warning: "warning", + info: "info", +} as const; + +export type CardVariant = (typeof CardVariant)[keyof typeof CardVariant]; + +const variantColors = { + default: "#868994", + fail: "#f54280", + pass: "#4ade80", + warning: "#fbbf24", + info: "#60a5fa", +} as const; + +type BadgeVariant = keyof typeof variantColors; + +const badgeVariants = cva( + ["flex", "items-center", "justify-center", "gap-0.5", "rounded-full"], + { + variants: { + variant: { + [CardVariant.default]: "bg-[#535359]", + [CardVariant.fail]: "bg-[#432232]", + [CardVariant.pass]: "bg-[#204237]", + [CardVariant.warning]: "bg-[#3d3520]", + [CardVariant.info]: "bg-[#1e3a5f]", + }, + size: { + sm: "px-1 text-xs", + md: "px-1.5 text-sm", + lg: "px-2 text-base", + }, + }, + defaultVariants: { + variant: CardVariant.fail, + size: "md", + }, + }, +); + +const badgeIconVariants = cva("", { + variants: { + size: { + sm: "h-2.5 w-2.5", + md: "h-3 w-3", + lg: "h-4 w-4", + }, + }, + defaultVariants: { + size: "md", + }, +}); + +const labelTextVariants = cva( + "leading-6 font-semibold text-zinc-300 dark:text-zinc-300", + { + variants: { + size: { + sm: "text-xs", + md: "text-sm", + lg: "text-base", + }, + }, + defaultVariants: { + size: "md", + }, + }, +); + +const statIconVariants = cva("text-zinc-300 dark:text-zinc-300", { + variants: { + size: { + sm: "h-2.5 w-2.5", + md: "h-3 w-3", + lg: "h-3.5 w-3.5", + }, + }, + defaultVariants: { + size: "md", + }, +}); + +const statLabelVariants = cva( + "leading-5 font-medium text-zinc-300 dark:text-zinc-300", + { + variants: { + size: { + sm: "text-xs", + md: "text-sm", + lg: "text-base", + }, + }, + defaultVariants: { + size: "md", + }, + }, +); + +export interface ResourceStatsCardContentProps + extends React.HTMLAttributes { + badge: { + icon: LucideIcon; + count: number | string; + variant?: CardVariant; + }; + label: string; + stats?: StatItem[]; + accentColor?: string; + size?: "sm" | "md" | "lg"; + ref?: React.Ref; +} + +export const ResourceStatsCardContent = ({ + badge, + label, + stats = [], + accentColor, + size = "md", + className, + ref, + ...props +}: ResourceStatsCardContentProps) => { + const BadgeIcon = badge.icon; + const badgeVariant: BadgeVariant = badge.variant || "fail"; + + // Determine accent line color + const lineColor = accentColor || variantColors[badgeVariant] || "#d4d4d8"; + + return ( +
+ {/* Badge and Label Row */} +
+ {/* Badge */} +
+ + + {badge.count} + +
+ + {/* Label */} + {label} +
+ + {/* Stats Section */} + {stats.length > 0 && ( +
+ {/* Vertical Accent Line */} +
+
+
+ + {/* Stats List */} +
+ {stats.map((stat, index) => { + const StatIcon = stat.icon; + return ( +
+ + + {stat.label} + +
+ ); + })} +
+
+ )} +
+ ); +}; + +ResourceStatsCardContent.displayName = "ResourceStatsCardContent"; diff --git a/ui/components/shadcn/resource-stats-card/resource-stats-card-divider.tsx b/ui/components/shadcn/resource-stats-card/resource-stats-card-divider.tsx new file mode 100644 index 0000000000..3ec8d57ee4 --- /dev/null +++ b/ui/components/shadcn/resource-stats-card/resource-stats-card-divider.tsx @@ -0,0 +1,59 @@ +import { cva, type VariantProps } from "class-variance-authority"; + +import { cn } from "@/lib/utils"; + +const dividerVariants = cva("flex items-center justify-center", { + variants: { + spacing: { + sm: "px-2", + md: "px-[23px]", + lg: "px-8", + }, + orientation: { + vertical: "h-full", + horizontal: "w-full", + }, + }, + defaultVariants: { + spacing: "md", + orientation: "vertical", + }, +}); + +const lineVariants = cva("bg-[rgba(39,39,42,1)]", { + variants: { + orientation: { + vertical: "h-full w-px", + horizontal: "w-full h-px", + }, + }, + defaultVariants: { + orientation: "vertical", + }, +}); + +export interface ResourceStatsCardDividerProps + extends React.HTMLAttributes, + VariantProps { + ref?: React.Ref; +} + +export const ResourceStatsCardDivider = ({ + className, + spacing, + orientation, + ref, + ...props +}: ResourceStatsCardDividerProps) => { + return ( +
+
+
+ ); +}; + +ResourceStatsCardDivider.displayName = "ResourceStatsCardDivider"; diff --git a/ui/components/shadcn/resource-stats-card/resource-stats-card-header.tsx b/ui/components/shadcn/resource-stats-card/resource-stats-card-header.tsx new file mode 100644 index 0000000000..2a4068e998 --- /dev/null +++ b/ui/components/shadcn/resource-stats-card/resource-stats-card-header.tsx @@ -0,0 +1,103 @@ +import { cva, type VariantProps } from "class-variance-authority"; +import { LucideIcon } from "lucide-react"; + +import { cn } from "@/lib/utils"; + +const headerVariants = cva("flex w-full items-center gap-1", { + variants: { + size: { + sm: "", + md: "", + lg: "", + }, + }, + defaultVariants: { + size: "md", + }, +}); + +const iconVariants = cva("text-zinc-300 dark:text-zinc-300", { + variants: { + size: { + sm: "h-3.5 w-3.5", + md: "h-4 w-4", + lg: "h-5 w-5", + }, + }, + defaultVariants: { + size: "md", + }, +}); + +const titleVariants = cva( + "leading-7 font-semibold text-zinc-300 dark:text-zinc-300", + { + variants: { + size: { + sm: "text-sm", + md: "text-base", + lg: "text-lg", + }, + }, + defaultVariants: { + size: "md", + }, + }, +); + +const countVariants = cva( + "leading-4 font-normal text-zinc-300 dark:text-zinc-300", + { + variants: { + size: { + sm: "text-[9px]", + md: "text-[10px]", + lg: "text-xs", + }, + }, + defaultVariants: { + size: "md", + }, + }, +); + +export interface ResourceStatsCardHeaderProps + extends React.HTMLAttributes, + VariantProps { + icon: LucideIcon; + title: string; + resourceCount?: number | string; + ref?: React.Ref; +} + +export const ResourceStatsCardHeader = ({ + icon: Icon, + title, + resourceCount, + size = "md", + className, + ref, + ...props +}: ResourceStatsCardHeaderProps) => { + return ( +
+
+ + {title} +
+ {resourceCount !== undefined && ( + + {typeof resourceCount === "number" + ? `${resourceCount} Resources` + : resourceCount} + + )} +
+ ); +}; + +ResourceStatsCardHeader.displayName = "ResourceStatsCardHeader"; diff --git a/ui/components/shadcn/resource-stats-card/resource-stats-card.tsx b/ui/components/shadcn/resource-stats-card/resource-stats-card.tsx new file mode 100644 index 0000000000..7acbd103e3 --- /dev/null +++ b/ui/components/shadcn/resource-stats-card/resource-stats-card.tsx @@ -0,0 +1,164 @@ +import { cva, type VariantProps } from "class-variance-authority"; +import { LucideIcon } from "lucide-react"; + +import { cn } from "@/lib/utils"; + +import { ResourceStatsCardContainer } from "./resource-stats-card-container"; +import type { StatItem } from "./resource-stats-card-content"; +import { + CardVariant, + ResourceStatsCardContent, +} from "./resource-stats-card-content"; +import { ResourceStatsCardHeader } from "./resource-stats-card-header"; + +export type { StatItem }; + +// Todo: when the design system is ready, we must use the colors from the design system (semantic colors) +// Variant styles using CVA for type safety and consistency +// Colors are exact HEX values from Figma design system +const cardVariants = cva("", { + variants: { + variant: { + [CardVariant.default]: "", + // Fail variant - rgba(67,34,50) from Figma + [CardVariant.fail]: + "border-[rgba(67,34,50,0.5)] bg-[rgba(67,34,50,0.2)] dark:border-[rgba(67,34,50,0.7)] dark:bg-[rgba(67,34,50,0.3)]", + // Pass variant - rgba(32,66,55) from Figma + [CardVariant.pass]: + "border-[rgba(32,66,55,0.5)] bg-[rgba(32,66,55,0.2)] dark:border-[rgba(32,66,55,0.7)] dark:bg-[rgba(32,66,55,0.3)]", + // Warning variant - rgba(61,53,32) from Figma + [CardVariant.warning]: + "border-[rgba(61,53,32,0.5)] bg-[rgba(61,53,32,0.2)] dark:border-[rgba(61,53,32,0.7)] dark:bg-[rgba(61,53,32,0.3)]", + // Info variant - rgba(30,58,95) from Figma + [CardVariant.info]: + "border-[rgba(30,58,95,0.5)] bg-[rgba(30,58,95,0.2)] dark:border-[rgba(30,58,95,0.7)] dark:bg-[rgba(30,58,95,0.3)]", + }, + size: { + sm: "px-2 py-1.5 gap-1", + md: "px-3 py-2 gap-2", + lg: "px-4 py-3 gap-3", + }, + }, + defaultVariants: { + variant: CardVariant.default, + size: "md", + }, +}); + +export interface ResourceStatsCardProps + extends Omit, "color">, + VariantProps { + // Optional header (icon + title + resource count) + header?: { + icon: LucideIcon; + title: string; + resourceCount?: number | string; + }; + + // Empty state message (when there's no data to display) + emptyState?: { + message: string; + }; + + // Main badge (top section) - optional when using empty state + badge?: { + icon: LucideIcon; + count: number | string; + variant?: CardVariant; + }; + + // Main label - optional when using empty state + label?: string; + + // Vertical accent line color (optional, auto-determined from variant) + accentColor?: string; + + // Sub-statistics array (flexible items) + stats?: StatItem[]; + + // Render without container (no border, background, padding) - useful for composing multiple cards in a custom container + containerless?: boolean; + + // Ref for the root element + ref?: React.Ref; +} + +export const ResourceStatsCard = ({ + header, + emptyState, + badge, + label, + accentColor, + stats = [], + variant = CardVariant.default, + size = "md", + containerless = false, + className, + ref, + ...props +}: ResourceStatsCardProps) => { + // Resolve size to ensure it's not null (CVA can return null but we need a defined value) + const resolvedSize = size || "md"; + + // If containerless, render without outer wrapper + if (containerless) { + return ( +
+ {header && } + {emptyState ? ( +
+

+ {emptyState.message} +

+
+ ) : ( + badge && + label && ( + + ) + )} +
+ ); + } + + // Otherwise, render with container + return ( + + {header && } + {emptyState ? ( +
+

+ {emptyState.message} +

+
+ ) : ( + badge && + label && ( + + ) + )} +
+ ); +}; + +ResourceStatsCard.displayName = "ResourceStatsCard"; diff --git a/ui/components/ui/sidebar/menu.tsx b/ui/components/ui/sidebar/menu.tsx index 2e192093e1..4047db376c 100644 --- a/ui/components/ui/sidebar/menu.tsx +++ b/ui/components/ui/sidebar/menu.tsx @@ -69,11 +69,13 @@ const hideMenuItems = (menuGroups: GroupProps[], labelsToHide: string[]) => { export const Menu = ({ isOpen }: { isOpen: boolean }) => { const pathname = usePathname(); const { permissions } = useAuth(); - const { hasProviders, openMutelistModal } = useUIStore(); + const { hasProviders, openMutelistModal, requestMutelistModalOpen } = + useUIStore(); const menuList = getMenuList({ pathname, hasProviders, openMutelistModal, + requestMutelistModalOpen, }); const labelsToHide = MENU_HIDE_RULES.filter((rule) => diff --git a/ui/dependency-log.json b/ui/dependency-log.json index 95acb9da32..4677a082eb 100644 --- a/ui/dependency-log.json +++ b/ui/dependency-log.json @@ -5,7 +5,7 @@ "from": "1.0.59", "to": "1.0.59", "strategy": "installed", - "generatedAt": "2025-10-01T11:13:12.025Z" + "generatedAt": "2025-10-22T12:36:37.962Z" }, { "section": "dependencies", @@ -13,7 +13,7 @@ "from": "2.0.59", "to": "2.0.59", "strategy": "installed", - "generatedAt": "2025-10-01T11:13:12.025Z" + "generatedAt": "2025-10-22T12:36:37.962Z" }, { "section": "dependencies", @@ -21,15 +21,15 @@ "from": "2.8.4", "to": "2.8.4", "strategy": "installed", - "generatedAt": "2025-09-29T14:26:25.838Z" + "generatedAt": "2025-10-22T12:36:37.962Z" }, { "section": "dependencies", "name": "@hookform/resolvers", - "from": "3.10.0", + "from": "5.2.2", "to": "5.2.2", "strategy": "installed", - "generatedAt": "2025-10-01T15:09:44.056Z" + "generatedAt": "2025-10-22T12:36:37.962Z" }, { "section": "dependencies", @@ -37,7 +37,7 @@ "from": "0.3.77", "to": "0.3.77", "strategy": "installed", - "generatedAt": "2025-09-23T10:22:08.630Z" + "generatedAt": "2025-10-22T12:36:37.962Z" }, { "section": "dependencies", @@ -45,23 +45,23 @@ "from": "0.4.9", "to": "0.4.9", "strategy": "installed", - "generatedAt": "2025-09-23T10:22:08.630Z" + "generatedAt": "2025-10-22T12:36:37.962Z" }, { "section": "dependencies", "name": "@langchain/langgraph-supervisor", - "from": "0.0.12", + "from": "0.0.20", "to": "0.0.20", "strategy": "installed", - "generatedAt": "2025-09-23T10:22:08.630Z" + "generatedAt": "2025-10-22T12:36:37.962Z" }, { "section": "dependencies", "name": "@langchain/openai", - "from": "0.6.9", + "from": "0.5.18", "to": "0.5.18", "strategy": "installed", - "generatedAt": "2025-09-23T10:22:08.630Z" + "generatedAt": "2025-10-22T12:36:37.962Z" }, { "section": "dependencies", @@ -69,7 +69,7 @@ "from": "15.3.5", "to": "15.3.5", "strategy": "installed", - "generatedAt": "2025-09-10T11:50:17.548Z" + "generatedAt": "2025-10-22T12:36:37.962Z" }, { "section": "dependencies", @@ -77,7 +77,7 @@ "from": "1.1.14", "to": "1.1.14", "strategy": "installed", - "generatedAt": "2025-09-10T11:50:17.548Z" + "generatedAt": "2025-10-22T12:36:37.962Z" }, { "section": "dependencies", @@ -85,7 +85,7 @@ "from": "1.1.14", "to": "1.1.14", "strategy": "installed", - "generatedAt": "2025-09-10T11:50:17.548Z" + "generatedAt": "2025-10-22T12:36:37.962Z" }, { "section": "dependencies", @@ -93,7 +93,7 @@ "from": "2.1.15", "to": "2.1.15", "strategy": "installed", - "generatedAt": "2025-09-10T11:50:17.548Z" + "generatedAt": "2025-10-22T12:36:37.962Z" }, { "section": "dependencies", @@ -101,7 +101,7 @@ "from": "1.3.2", "to": "1.3.2", "strategy": "installed", - "generatedAt": "2025-09-10T11:50:17.548Z" + "generatedAt": "2025-10-22T12:36:37.962Z" }, { "section": "dependencies", @@ -109,7 +109,7 @@ "from": "2.1.7", "to": "2.1.7", "strategy": "installed", - "generatedAt": "2025-09-10T11:50:17.548Z" + "generatedAt": "2025-10-22T12:36:37.962Z" }, { "section": "dependencies", @@ -117,7 +117,7 @@ "from": "2.2.5", "to": "2.2.5", "strategy": "installed", - "generatedAt": "2025-09-10T11:50:17.548Z" + "generatedAt": "2025-10-22T12:36:37.962Z" }, { "section": "dependencies", @@ -125,7 +125,7 @@ "from": "1.2.3", "to": "1.2.3", "strategy": "installed", - "generatedAt": "2025-09-10T11:50:17.548Z" + "generatedAt": "2025-10-22T12:36:37.962Z" }, { "section": "dependencies", @@ -133,7 +133,7 @@ "from": "1.2.14", "to": "1.2.14", "strategy": "installed", - "generatedAt": "2025-09-10T11:50:17.548Z" + "generatedAt": "2025-10-22T12:36:37.962Z" }, { "section": "dependencies", @@ -141,7 +141,7 @@ "from": "3.9.4", "to": "3.9.4", "strategy": "installed", - "generatedAt": "2025-09-10T11:50:17.548Z" + "generatedAt": "2025-10-22T12:36:37.962Z" }, { "section": "dependencies", @@ -149,7 +149,7 @@ "from": "3.8.12", "to": "3.8.12", "strategy": "installed", - "generatedAt": "2025-09-10T11:50:17.548Z" + "generatedAt": "2025-10-22T12:36:37.962Z" }, { "section": "dependencies", @@ -157,7 +157,7 @@ "from": "4.1.13", "to": "4.1.13", "strategy": "installed", - "generatedAt": "2025-09-24T15:04:48.761Z" + "generatedAt": "2025-10-22T12:36:37.962Z" }, { "section": "dependencies", @@ -165,7 +165,7 @@ "from": "0.5.16", "to": "0.5.16", "strategy": "installed", - "generatedAt": "2025-09-10T11:50:17.548Z" + "generatedAt": "2025-10-22T12:36:37.962Z" }, { "section": "dependencies", @@ -173,7 +173,7 @@ "from": "8.21.3", "to": "8.21.3", "strategy": "installed", - "generatedAt": "2025-09-10T11:50:17.548Z" + "generatedAt": "2025-10-22T12:36:37.962Z" }, { "section": "dependencies", @@ -181,15 +181,15 @@ "from": "4.0.9", "to": "4.0.9", "strategy": "installed", - "generatedAt": "2025-09-10T11:50:17.548Z" + "generatedAt": "2025-10-22T12:36:37.962Z" }, { "section": "dependencies", "name": "ai", - "from": "4.3.16", + "from": "5.0.59", "to": "5.0.59", "strategy": "installed", - "generatedAt": "2025-10-01T10:03:22.788Z" + "generatedAt": "2025-10-22T12:36:37.962Z" }, { "section": "dependencies", @@ -197,7 +197,7 @@ "from": "6.0.2", "to": "6.0.2", "strategy": "installed", - "generatedAt": "2025-09-10T11:50:17.548Z" + "generatedAt": "2025-10-22T12:36:37.962Z" }, { "section": "dependencies", @@ -205,7 +205,7 @@ "from": "0.7.1", "to": "0.7.1", "strategy": "installed", - "generatedAt": "2025-09-10T11:50:17.548Z" + "generatedAt": "2025-10-22T12:36:37.962Z" }, { "section": "dependencies", @@ -213,7 +213,7 @@ "from": "2.1.1", "to": "2.1.1", "strategy": "installed", - "generatedAt": "2025-09-10T11:50:17.548Z" + "generatedAt": "2025-10-22T12:36:37.962Z" }, { "section": "dependencies", @@ -221,7 +221,7 @@ "from": "7.9.0", "to": "7.9.0", "strategy": "installed", - "generatedAt": "2025-10-16T10:46:11.221Z" + "generatedAt": "2025-10-22T12:36:37.962Z" }, { "section": "dependencies", @@ -229,7 +229,7 @@ "from": "4.1.0", "to": "4.1.0", "strategy": "installed", - "generatedAt": "2025-09-10T11:50:17.548Z" + "generatedAt": "2025-10-22T12:36:37.962Z" }, { "section": "dependencies", @@ -237,7 +237,7 @@ "from": "11.18.2", "to": "11.18.2", "strategy": "installed", - "generatedAt": "2025-09-10T11:50:17.548Z" + "generatedAt": "2025-10-22T12:36:37.962Z" }, { "section": "dependencies", @@ -245,7 +245,7 @@ "from": "10.7.16", "to": "10.7.16", "strategy": "installed", - "generatedAt": "2025-09-10T11:50:17.548Z" + "generatedAt": "2025-10-22T12:36:37.962Z" }, { "section": "dependencies", @@ -253,7 +253,7 @@ "from": "5.10.0", "to": "5.10.0", "strategy": "installed", - "generatedAt": "2025-09-10T11:50:17.548Z" + "generatedAt": "2025-10-22T12:36:37.962Z" }, { "section": "dependencies", @@ -261,7 +261,7 @@ "from": "4.1.0", "to": "4.1.0", "strategy": "installed", - "generatedAt": "2025-09-10T11:50:17.548Z" + "generatedAt": "2025-10-22T12:36:37.962Z" }, { "section": "dependencies", @@ -269,7 +269,7 @@ "from": "4.0.0", "to": "4.0.0", "strategy": "installed", - "generatedAt": "2025-09-10T11:50:17.548Z" + "generatedAt": "2025-10-22T12:36:37.962Z" }, { "section": "dependencies", @@ -277,7 +277,7 @@ "from": "0.543.0", "to": "0.543.0", "strategy": "installed", - "generatedAt": "2025-09-10T11:50:17.548Z" + "generatedAt": "2025-10-22T12:36:37.962Z" }, { "section": "dependencies", @@ -285,15 +285,15 @@ "from": "15.0.12", "to": "15.0.12", "strategy": "installed", - "generatedAt": "2025-09-10T11:50:17.548Z" + "generatedAt": "2025-10-22T12:36:37.962Z" }, { "section": "dependencies", "name": "next", - "from": "14.2.32", + "from": "15.5.3", "to": "15.5.3", "strategy": "installed", - "generatedAt": "2025-09-23T10:22:08.630Z" + "generatedAt": "2025-10-22T12:36:37.962Z" }, { "section": "dependencies", @@ -301,7 +301,7 @@ "from": "5.0.0-beta.29", "to": "5.0.0-beta.29", "strategy": "installed", - "generatedAt": "2025-09-10T11:50:17.548Z" + "generatedAt": "2025-10-22T12:36:37.962Z" }, { "section": "dependencies", @@ -309,7 +309,7 @@ "from": "0.2.1", "to": "0.2.1", "strategy": "installed", - "generatedAt": "2025-09-10T11:50:17.548Z" + "generatedAt": "2025-10-22T12:36:37.962Z" }, { "section": "dependencies", @@ -317,23 +317,23 @@ "from": "1.4.2", "to": "1.4.2", "strategy": "installed", - "generatedAt": "2025-09-10T11:50:17.548Z" + "generatedAt": "2025-10-22T12:36:37.962Z" }, { "section": "dependencies", "name": "react", - "from": "18.3.1", + "from": "19.1.1", "to": "19.1.1", "strategy": "installed", - "generatedAt": "2025-09-23T10:22:08.630Z" + "generatedAt": "2025-10-22T12:36:37.962Z" }, { "section": "dependencies", "name": "react-dom", - "from": "18.3.1", + "from": "19.1.1", "to": "19.1.1", "strategy": "installed", - "generatedAt": "2025-09-23T10:22:08.630Z" + "generatedAt": "2025-10-22T12:36:37.962Z" }, { "section": "dependencies", @@ -341,7 +341,7 @@ "from": "7.62.0", "to": "7.62.0", "strategy": "installed", - "generatedAt": "2025-09-10T11:50:17.548Z" + "generatedAt": "2025-10-22T12:36:37.962Z" }, { "section": "dependencies", @@ -349,7 +349,7 @@ "from": "10.1.0", "to": "10.1.0", "strategy": "installed", - "generatedAt": "2025-09-10T11:50:17.548Z" + "generatedAt": "2025-10-22T12:36:37.962Z" }, { "section": "dependencies", @@ -357,7 +357,7 @@ "from": "2.15.4", "to": "2.15.4", "strategy": "installed", - "generatedAt": "2025-09-10T11:50:17.548Z" + "generatedAt": "2025-10-22T12:36:37.962Z" }, { "section": "dependencies", @@ -365,7 +365,7 @@ "from": "3.13.0", "to": "3.13.0", "strategy": "installed", - "generatedAt": "2025-09-10T11:50:17.548Z" + "generatedAt": "2025-10-22T12:36:37.962Z" }, { "section": "dependencies", @@ -373,15 +373,7 @@ "from": "0.0.1", "to": "0.0.1", "strategy": "installed", - "generatedAt": "2025-09-10T11:50:17.548Z" - }, - { - "section": "dependencies", - "name": "shadcn", - "from": "3.2.1", - "to": "3.2.1", - "strategy": "installed", - "generatedAt": "2025-09-10T11:50:17.548Z" + "generatedAt": "2025-10-22T12:36:37.962Z" }, { "section": "dependencies", @@ -389,7 +381,7 @@ "from": "0.33.5", "to": "0.33.5", "strategy": "installed", - "generatedAt": "2025-09-10T11:50:17.548Z" + "generatedAt": "2025-10-22T12:36:37.962Z" }, { "section": "dependencies", @@ -397,7 +389,7 @@ "from": "3.3.1", "to": "3.3.1", "strategy": "installed", - "generatedAt": "2025-09-10T11:50:17.548Z" + "generatedAt": "2025-10-22T12:36:37.962Z" }, { "section": "dependencies", @@ -405,7 +397,7 @@ "from": "1.0.7", "to": "1.0.7", "strategy": "installed", - "generatedAt": "2025-09-10T11:50:17.548Z" + "generatedAt": "2025-10-22T12:36:37.962Z" }, { "section": "dependencies", @@ -413,7 +405,15 @@ "from": "3.1.0", "to": "3.1.0", "strategy": "installed", - "generatedAt": "2025-10-16T10:46:11.221Z" + "generatedAt": "2025-10-22T12:36:37.962Z" + }, + { + "section": "dependencies", + "name": "tw-animate-css", + "from": "1.4.0", + "to": "1.4.0", + "strategy": "installed", + "generatedAt": "2025-10-22T12:36:37.962Z" }, { "section": "dependencies", @@ -421,7 +421,7 @@ "from": "11.1.0", "to": "11.1.0", "strategy": "installed", - "generatedAt": "2025-09-10T11:50:17.548Z" + "generatedAt": "2025-10-22T12:36:37.962Z" }, { "section": "dependencies", @@ -429,23 +429,23 @@ "from": "2.0.2", "to": "2.0.2", "strategy": "installed", - "generatedAt": "2025-10-16T10:46:11.221Z" + "generatedAt": "2025-10-22T12:36:37.962Z" }, { "section": "dependencies", "name": "zod", - "from": "3.25.73", + "from": "4.1.11", "to": "4.1.11", "strategy": "installed", - "generatedAt": "2025-10-01T09:40:25.207Z" + "generatedAt": "2025-10-22T12:36:37.962Z" }, { "section": "dependencies", "name": "zustand", - "from": "4.5.7", + "from": "5.0.8", "to": "5.0.8", "strategy": "installed", - "generatedAt": "2025-10-01T09:40:25.207Z" + "generatedAt": "2025-10-22T12:36:37.962Z" }, { "section": "devDependencies", @@ -453,15 +453,15 @@ "from": "5.2.1", "to": "5.2.1", "strategy": "installed", - "generatedAt": "2025-09-10T11:50:17.554Z" + "generatedAt": "2025-10-22T12:36:37.962Z" }, { "section": "devDependencies", "name": "@playwright/test", - "from": "1.53.2", - "to": "1.53.2", + "from": "1.56.1", + "to": "1.56.1", "strategy": "installed", - "generatedAt": "2025-09-10T11:50:17.554Z" + "generatedAt": "2025-10-22T12:36:37.962Z" }, { "section": "devDependencies", @@ -469,7 +469,7 @@ "from": "7.4.3", "to": "7.4.3", "strategy": "installed", - "generatedAt": "2025-10-16T10:46:11.221Z" + "generatedAt": "2025-10-22T12:36:37.962Z" }, { "section": "devDependencies", @@ -477,23 +477,23 @@ "from": "20.5.7", "to": "20.5.7", "strategy": "installed", - "generatedAt": "2025-09-10T11:50:17.554Z" + "generatedAt": "2025-10-22T12:36:37.962Z" }, { "section": "devDependencies", "name": "@types/react", - "from": "18.3.3", + "from": "19.1.13", "to": "19.1.13", "strategy": "installed", - "generatedAt": "2025-09-23T10:22:08.630Z" + "generatedAt": "2025-10-22T12:36:37.962Z" }, { "section": "devDependencies", "name": "@types/react-dom", - "from": "18.3.0", + "from": "19.1.9", "to": "19.1.9", "strategy": "installed", - "generatedAt": "2025-09-23T10:22:08.630Z" + "generatedAt": "2025-10-22T12:36:37.962Z" }, { "section": "devDependencies", @@ -501,7 +501,7 @@ "from": "3.1.5", "to": "3.1.5", "strategy": "installed", - "generatedAt": "2025-10-16T10:46:11.221Z" + "generatedAt": "2025-10-22T12:36:37.962Z" }, { "section": "devDependencies", @@ -509,7 +509,7 @@ "from": "10.0.0", "to": "10.0.0", "strategy": "installed", - "generatedAt": "2025-09-10T11:50:17.554Z" + "generatedAt": "2025-10-22T12:36:37.962Z" }, { "section": "devDependencies", @@ -517,7 +517,7 @@ "from": "7.18.0", "to": "7.18.0", "strategy": "installed", - "generatedAt": "2025-09-10T11:50:17.554Z" + "generatedAt": "2025-10-22T12:36:37.962Z" }, { "section": "devDependencies", @@ -525,7 +525,7 @@ "from": "7.18.0", "to": "7.18.0", "strategy": "installed", - "generatedAt": "2025-09-10T11:50:17.554Z" + "generatedAt": "2025-10-22T12:36:37.962Z" }, { "section": "devDependencies", @@ -533,7 +533,7 @@ "from": "10.4.19", "to": "10.4.19", "strategy": "installed", - "generatedAt": "2025-09-10T11:50:17.554Z" + "generatedAt": "2025-10-22T12:36:37.962Z" }, { "section": "devDependencies", @@ -541,7 +541,7 @@ "from": "19.1.0-rc.3", "to": "19.1.0-rc.3", "strategy": "installed", - "generatedAt": "2025-09-23T10:22:08.630Z" + "generatedAt": "2025-10-22T12:36:37.962Z" }, { "section": "devDependencies", @@ -549,15 +549,15 @@ "from": "8.57.1", "to": "8.57.1", "strategy": "installed", - "generatedAt": "2025-09-10T11:50:17.554Z" + "generatedAt": "2025-10-22T12:36:37.962Z" }, { "section": "devDependencies", "name": "eslint-config-next", - "from": "14.2.32", + "from": "15.5.3", "to": "15.5.3", "strategy": "installed", - "generatedAt": "2025-09-23T10:22:08.630Z" + "generatedAt": "2025-10-22T12:36:37.962Z" }, { "section": "devDependencies", @@ -565,7 +565,7 @@ "from": "10.1.5", "to": "10.1.5", "strategy": "installed", - "generatedAt": "2025-09-10T11:50:17.554Z" + "generatedAt": "2025-10-22T12:36:37.962Z" }, { "section": "devDependencies", @@ -573,7 +573,7 @@ "from": "2.32.0", "to": "2.32.0", "strategy": "installed", - "generatedAt": "2025-09-10T11:50:17.554Z" + "generatedAt": "2025-10-22T12:36:37.962Z" }, { "section": "devDependencies", @@ -581,7 +581,7 @@ "from": "6.10.2", "to": "6.10.2", "strategy": "installed", - "generatedAt": "2025-09-10T11:50:17.554Z" + "generatedAt": "2025-10-22T12:36:37.962Z" }, { "section": "devDependencies", @@ -589,7 +589,7 @@ "from": "11.1.0", "to": "11.1.0", "strategy": "installed", - "generatedAt": "2025-09-10T11:50:17.554Z" + "generatedAt": "2025-10-22T12:36:37.962Z" }, { "section": "devDependencies", @@ -597,7 +597,7 @@ "from": "5.5.1", "to": "5.5.1", "strategy": "installed", - "generatedAt": "2025-09-10T11:50:17.554Z" + "generatedAt": "2025-10-22T12:36:37.962Z" }, { "section": "devDependencies", @@ -605,7 +605,7 @@ "from": "7.37.5", "to": "7.37.5", "strategy": "installed", - "generatedAt": "2025-09-10T11:50:17.554Z" + "generatedAt": "2025-10-22T12:36:37.962Z" }, { "section": "devDependencies", @@ -613,7 +613,7 @@ "from": "4.6.2", "to": "4.6.2", "strategy": "installed", - "generatedAt": "2025-09-10T11:50:17.554Z" + "generatedAt": "2025-10-22T12:36:37.962Z" }, { "section": "devDependencies", @@ -621,7 +621,7 @@ "from": "3.0.1", "to": "3.0.1", "strategy": "installed", - "generatedAt": "2025-09-10T11:50:17.554Z" + "generatedAt": "2025-10-22T12:36:37.962Z" }, { "section": "devDependencies", @@ -629,7 +629,7 @@ "from": "12.1.1", "to": "12.1.1", "strategy": "installed", - "generatedAt": "2025-09-10T11:50:17.554Z" + "generatedAt": "2025-10-22T12:36:37.962Z" }, { "section": "devDependencies", @@ -637,7 +637,7 @@ "from": "3.2.0", "to": "3.2.0", "strategy": "installed", - "generatedAt": "2025-09-10T11:50:17.554Z" + "generatedAt": "2025-10-22T12:36:37.962Z" }, { "section": "devDependencies", @@ -645,7 +645,7 @@ "from": "9.1.7", "to": "9.1.7", "strategy": "installed", - "generatedAt": "2025-09-10T11:50:17.554Z" + "generatedAt": "2025-10-22T12:36:37.962Z" }, { "section": "devDependencies", @@ -653,7 +653,7 @@ "from": "15.5.2", "to": "15.5.2", "strategy": "installed", - "generatedAt": "2025-09-10T11:50:17.554Z" + "generatedAt": "2025-10-22T12:36:37.962Z" }, { "section": "devDependencies", @@ -661,7 +661,7 @@ "from": "8.4.38", "to": "8.4.38", "strategy": "installed", - "generatedAt": "2025-09-10T11:50:17.554Z" + "generatedAt": "2025-10-22T12:36:37.962Z" }, { "section": "devDependencies", @@ -669,15 +669,23 @@ "from": "3.6.2", "to": "3.6.2", "strategy": "installed", - "generatedAt": "2025-09-10T11:50:17.554Z" + "generatedAt": "2025-10-22T12:36:37.962Z" }, { "section": "devDependencies", "name": "prettier-plugin-tailwindcss", - "from": "0.6.13", + "from": "0.6.14", "to": "0.6.14", "strategy": "installed", - "generatedAt": "2025-09-24T13:59:11.231Z" + "generatedAt": "2025-10-22T12:36:37.962Z" + }, + { + "section": "devDependencies", + "name": "shadcn", + "from": "3.4.1", + "to": "3.4.1", + "strategy": "installed", + "generatedAt": "2025-10-22T12:36:37.962Z" }, { "section": "devDependencies", @@ -685,15 +693,15 @@ "from": "0.1.20", "to": "0.1.20", "strategy": "installed", - "generatedAt": "2025-09-10T11:50:17.554Z" + "generatedAt": "2025-10-22T12:36:37.962Z" }, { "section": "devDependencies", "name": "tailwindcss", - "from": "3.4.3", + "from": "4.1.13", "to": "4.1.13", "strategy": "installed", - "generatedAt": "2025-09-24T13:59:11.231Z" + "generatedAt": "2025-10-22T12:36:37.962Z" }, { "section": "devDependencies", @@ -701,6 +709,6 @@ "from": "5.5.4", "to": "5.5.4", "strategy": "installed", - "generatedAt": "2025-09-10T11:50:17.554Z" + "generatedAt": "2025-10-22T12:36:37.962Z" } ] diff --git a/ui/hooks/use-credentials-form.ts b/ui/hooks/use-credentials-form.ts index 268d714d71..2690b9307a 100644 --- a/ui/hooks/use-credentials-form.ts +++ b/ui/hooks/use-credentials-form.ts @@ -40,8 +40,8 @@ export const useCredentialsForm = ({ if (providerType === "gcp" && via === "service-account") { return addCredentialsServiceAccountFormSchema(providerType); } - // For GitHub, we need to pass the via parameter to determine which fields are required - if (providerType === "github") { + // For GitHub and M365, we need to pass the via parameter to determine which fields are required + if (providerType === "github" || providerType === "m365") { return addCredentialsFormSchema(providerType, via); } return addCredentialsFormSchema(providerType); @@ -99,13 +99,27 @@ export const useCredentialsForm = ({ [ProviderCredentialFields.TENANT_ID]: "", }; case "m365": + // M365 credentials based on via parameter + if (via === "app_client_secret") { + return { + ...baseDefaults, + [ProviderCredentialFields.CLIENT_ID]: "", + [ProviderCredentialFields.CLIENT_SECRET]: "", + [ProviderCredentialFields.TENANT_ID]: "", + }; + } + if (via === "app_certificate") { + return { + ...baseDefaults, + [ProviderCredentialFields.CLIENT_ID]: "", + [ProviderCredentialFields.CERTIFICATE_CONTENT]: "", + [ProviderCredentialFields.TENANT_ID]: "", + }; + } return { ...baseDefaults, [ProviderCredentialFields.CLIENT_ID]: "", - [ProviderCredentialFields.CLIENT_SECRET]: "", [ProviderCredentialFields.TENANT_ID]: "", - [ProviderCredentialFields.USER]: "", - [ProviderCredentialFields.PASSWORD]: "", }; case "gcp": return { @@ -146,9 +160,14 @@ export const useCredentialsForm = ({ } }; + const defaultValues = getDefaultValues(); + const form = useForm({ resolver: zodResolver(formSchema), - defaultValues: getDefaultValues(), + defaultValues: defaultValues, + mode: "onSubmit", + reValidateMode: "onChange", + criteriaMode: "all", // Show all errors for each field }); const { handleServerResponse } = useFormServerErrors( @@ -169,6 +188,7 @@ export const useCredentialsForm = ({ // Filter out empty values first, then append all remaining values const filteredValues = filterEmptyValues(values); + Object.entries(filteredValues).forEach(([key, value]) => { formData.append(key, value); }); @@ -181,9 +201,12 @@ export const useCredentialsForm = ({ } }; + const { isSubmitting, errors } = form.formState; + return { form, - isLoading: form.formState.isSubmitting, + isLoading: isSubmitting, + errors, handleSubmit, handleBackStep, searchParamsObj, diff --git a/ui/lib/menu-list.ts b/ui/lib/menu-list.ts index 2b465869e3..e2e83f0951 100644 --- a/ui/lib/menu-list.ts +++ b/ui/lib/menu-list.ts @@ -18,6 +18,7 @@ import { VolumeX, Warehouse, } from "lucide-react"; +import type { MouseEvent } from "react"; import { ProwlerShort } from "@/components/icons"; import { @@ -39,12 +40,14 @@ interface MenuListOptions { pathname: string; hasProviders?: boolean; openMutelistModal?: () => void; + requestMutelistModalOpen?: () => void; } export const getMenuList = ({ pathname, hasProviders, openMutelistModal, + requestMutelistModalOpen, }: MenuListOptions): GroupProps[] => { return [ { @@ -164,12 +167,28 @@ export const getMenuList = ({ submenus: [ { href: "/providers", label: "Cloud Providers", icon: CloudCog }, { - // Use trailing slash to prevent both menu items from being active at /providers - href: "/providers/", + href: "/providers", label: "Mutelist", icon: VolumeX, disabled: hasProviders === false, - onClick: openMutelistModal, + active: false, + onClick: (event: MouseEvent) => { + if (hasProviders === false) { + event.preventDefault(); + event.stopPropagation(); + return; + } + + requestMutelistModalOpen?.(); + + if (pathname !== "/providers") { + return; + } + + event.preventDefault(); + event.stopPropagation(); + openMutelistModal?.(); + }, }, { href: "/manage-groups", label: "Provider Groups", icon: Group }, { href: "/scans", label: "Scan Jobs", icon: Timer }, diff --git a/ui/lib/provider-credentials/build-crendentials.ts b/ui/lib/provider-credentials/build-crendentials.ts index 475702db0c..2a0abd31c7 100644 --- a/ui/lib/provider-credentials/build-crendentials.ts +++ b/ui/lib/provider-credentials/build-crendentials.ts @@ -80,14 +80,21 @@ export const buildAzureSecret = (formData: FormData) => { export const buildM365Secret = (formData: FormData) => { const secret = { - ...buildAzureSecret(formData), - [ProviderCredentialFields.USER]: getFormValue( + [ProviderCredentialFields.CLIENT_ID]: getFormValue( formData, - ProviderCredentialFields.USER, + ProviderCredentialFields.CLIENT_ID, ), - [ProviderCredentialFields.PASSWORD]: getFormValue( + [ProviderCredentialFields.TENANT_ID]: getFormValue( formData, - ProviderCredentialFields.PASSWORD, + ProviderCredentialFields.TENANT_ID, + ), + [ProviderCredentialFields.CLIENT_SECRET]: getFormValue( + formData, + ProviderCredentialFields.CLIENT_SECRET, + ), + [ProviderCredentialFields.CERTIFICATE_CONTENT]: getFormValue( + formData, + ProviderCredentialFields.CERTIFICATE_CONTENT, ), }; return filterEmptyValues(secret); diff --git a/ui/lib/provider-credentials/provider-credential-fields.ts b/ui/lib/provider-credentials/provider-credential-fields.ts index 32dc184292..635c74bf44 100644 --- a/ui/lib/provider-credentials/provider-credential-fields.ts +++ b/ui/lib/provider-credentials/provider-credential-fields.ts @@ -29,6 +29,7 @@ export const ProviderCredentialFields = { TENANT_ID: "tenant_id", USER: "user", PASSWORD: "password", + CERTIFICATE_CONTENT: "certificate_content", // GCP fields REFRESH_TOKEN: "refresh_token", @@ -70,6 +71,7 @@ export const ErrorPointers = { OAUTH_APP_TOKEN: "/data/attributes/secret/oauth_app_token", GITHUB_APP_ID: "/data/attributes/secret/github_app_id", GITHUB_APP_KEY: "/data/attributes/secret/github_app_key_content", + CERTIFICATE_CONTENT: "/data/attributes/secret/certificate_content", } as const; export type ErrorPointer = (typeof ErrorPointers)[keyof typeof ErrorPointers]; diff --git a/ui/lib/provider-helpers.ts b/ui/lib/provider-helpers.ts index becd9bc4f2..1bcf5d80bb 100644 --- a/ui/lib/provider-helpers.ts +++ b/ui/lib/provider-helpers.ts @@ -53,7 +53,7 @@ export const getProviderFormType = ( via?: string, ): ProviderFormType => { // Providers that need credential type selection - const needsSelector = ["aws", "gcp", "github"].includes(providerType); + const needsSelector = ["aws", "gcp", "github", "m365"].includes(providerType); // Show selector if no via parameter and provider needs it if (needsSelector && !via) { @@ -80,6 +80,14 @@ export const getProviderFormType = ( return "credentials"; } + // M365 credential types + if ( + providerType === "m365" && + ["app_client_secret", "app_certificate"].includes(via || "") + ) { + return "credentials"; + } + // Other providers go directly to credentials form if (!needsSelector) { return "credentials"; @@ -99,6 +107,8 @@ export const requiresBackButton = (via?: string | null): boolean => { "personal_access_token", "oauth_app", "github_app", + "app_client_secret", + "app_certificate", ]; return validViaTypes.includes(via); diff --git a/ui/package-lock.json b/ui/package-lock.json index 6a2467e54e..1530aa3134 100644 --- a/ui/package-lock.json +++ b/ui/package-lock.json @@ -56,11 +56,11 @@ "recharts": "2.15.4", "rss-parser": "3.13.0", "server-only": "0.0.1", - "shadcn": "3.2.1", "sharp": "0.33.5", "tailwind-merge": "3.3.1", "tailwindcss-animate": "1.0.7", "topojson-client": "3.1.0", + "tw-animate-css": "1.4.0", "uuid": "11.1.0", "world-atlas": "2.0.2", "zod": "4.1.11", @@ -68,7 +68,7 @@ }, "devDependencies": { "@iconify/react": "5.2.1", - "@playwright/test": "1.53.2", + "@playwright/test": "1.56.1", "@types/d3": "7.4.3", "@types/node": "20.5.7", "@types/react": "19.1.13", @@ -96,6 +96,7 @@ "postcss": "8.4.38", "prettier": "3.6.2", "prettier-plugin-tailwindcss": "0.6.14", + "shadcn": "3.4.1", "tailwind-variants": "0.1.20", "tailwindcss": "4.1.13", "typescript": "5.5.4" @@ -198,6 +199,7 @@ "version": "25.0.0", "resolved": "https://registry.npmjs.org/@antfu/ni/-/ni-25.0.0.tgz", "integrity": "sha512-9q/yCljni37pkMr4sPrI3G4jqdIk074+iukc5aFJl7kmDCCsiJrbZ6zKxnES1Gwg+i9RcDZwvktl23puGslmvA==", + "dev": true, "license": "MIT", "dependencies": { "ansis": "^4.0.0", @@ -257,6 +259,7 @@ "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", + "dev": true, "license": "MIT", "dependencies": { "@babel/helper-validator-identifier": "^7.27.1", @@ -271,6 +274,7 @@ "version": "7.28.4", "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.4.tgz", "integrity": "sha512-YsmSKC29MJwf0gF8Rjjrg5LQCmyh+j/nD8/eP7f+BeoQTKYqs9RoWbjGOdy0+1Ekr68RJZMUOPVQaQisnIo4Rw==", + "dev": true, "license": "MIT", "engines": { "node": ">=6.9.0" @@ -280,6 +284,7 @@ "version": "7.28.4", "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.4.tgz", "integrity": "sha512-2BCOP7TN8M+gVDj7/ht3hsaO/B/n5oDbiAyyvnRlNOs+u1o+JWNYTQrmpuNp1/Wq2gcFrI01JAW+paEKDMx/CA==", + "dev": true, "license": "MIT", "dependencies": { "@babel/code-frame": "^7.27.1", @@ -310,6 +315,7 @@ "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -319,6 +325,7 @@ "version": "7.28.3", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.3.tgz", "integrity": "sha512-3lSpxGgvnmZznmBkCRnVREPUFJv2wrv9iAoFDvADJc0ypmdOxdUtcLeBgBJ6zE0PMeTKnxeQzyk0xTBq4Ep7zw==", + "dev": true, "license": "MIT", "dependencies": { "@babel/parser": "^7.28.3", @@ -335,6 +342,7 @@ "version": "7.27.3", "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.27.3.tgz", "integrity": "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==", + "dev": true, "license": "MIT", "dependencies": { "@babel/types": "^7.27.3" @@ -347,6 +355,7 @@ "version": "7.27.2", "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz", "integrity": "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==", + "dev": true, "license": "MIT", "dependencies": { "@babel/compat-data": "^7.27.2", @@ -363,6 +372,7 @@ "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -372,6 +382,7 @@ "version": "7.28.3", "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.28.3.tgz", "integrity": "sha512-V9f6ZFIYSLNEbuGA/92uOvYsGCJNsuA8ESZ4ldc09bWk/j8H8TKiPw8Mk1eG6olpnO0ALHJmYfZvF4MEE4gajg==", + "dev": true, "license": "MIT", "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", @@ -393,6 +404,7 @@ "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -402,6 +414,7 @@ "version": "7.28.0", "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", + "dev": true, "license": "MIT", "engines": { "node": ">=6.9.0" @@ -411,6 +424,7 @@ "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.27.1.tgz", "integrity": "sha512-E5chM8eWjTp/aNoVpcbfM7mLxu9XGLWYise2eBKGQomAk/Mb4XoxyqXTZbuTohbsl8EKqdlMhnDI2CCLfcs9wA==", + "dev": true, "license": "MIT", "dependencies": { "@babel/traverse": "^7.27.1", @@ -424,6 +438,7 @@ "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz", "integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==", + "dev": true, "license": "MIT", "dependencies": { "@babel/traverse": "^7.27.1", @@ -437,6 +452,7 @@ "version": "7.28.3", "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.3.tgz", "integrity": "sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==", + "dev": true, "license": "MIT", "dependencies": { "@babel/helper-module-imports": "^7.27.1", @@ -454,6 +470,7 @@ "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.27.1.tgz", "integrity": "sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw==", + "dev": true, "license": "MIT", "dependencies": { "@babel/types": "^7.27.1" @@ -466,6 +483,7 @@ "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz", "integrity": "sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==", + "dev": true, "license": "MIT", "engines": { "node": ">=6.9.0" @@ -475,6 +493,7 @@ "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.27.1.tgz", "integrity": "sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA==", + "dev": true, "license": "MIT", "dependencies": { "@babel/helper-member-expression-to-functions": "^7.27.1", @@ -492,6 +511,7 @@ "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.27.1.tgz", "integrity": "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg==", + "dev": true, "license": "MIT", "dependencies": { "@babel/traverse": "^7.27.1", @@ -505,6 +525,7 @@ "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", + "devOptional": true, "license": "MIT", "engines": { "node": ">=6.9.0" @@ -514,6 +535,7 @@ "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz", "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==", + "devOptional": true, "license": "MIT", "engines": { "node": ">=6.9.0" @@ -523,6 +545,7 @@ "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", + "dev": true, "license": "MIT", "engines": { "node": ">=6.9.0" @@ -532,6 +555,7 @@ "version": "7.28.4", "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.4.tgz", "integrity": "sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==", + "dev": true, "license": "MIT", "dependencies": { "@babel/template": "^7.27.2", @@ -545,6 +569,7 @@ "version": "7.28.4", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.4.tgz", "integrity": "sha512-yZbBqeM6TkpP9du/I2pUZnJsRMGGvOuIrhjzC1AwHwW+6he4mni6Bp/m8ijn0iOuZuPI2BfkCoSRunpyjnrQKg==", + "dev": true, "license": "MIT", "dependencies": { "@babel/types": "^7.28.4" @@ -556,10 +581,27 @@ "node": ">=6.0.0" } }, + "node_modules/@babel/plugin-syntax-jsx": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.27.1.tgz", + "integrity": "sha512-y8YTNIeKoyhGd9O0Jiyzyyqk8gdjnumGTQPsz0xOZOQ2RmkVJeZ1vmmfIvFEKqucBG6axJGBZDE/7iI5suUI/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, "node_modules/@babel/plugin-syntax-typescript": { "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.27.1.tgz", "integrity": "sha512-xfYCBMxveHrRMnAWl1ZlPXOZjzkN82THFvLhQhFXFt81Z5HnN+EtUkZhv/zcKpmT3fzmWZB0ywiBrbC3vogbwQ==", + "dev": true, "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" @@ -571,10 +613,28 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/plugin-transform-modules-commonjs": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.27.1.tgz", + "integrity": "sha512-OJguuwlTYlN0gBZFRPqwOGNWssZjfIUdS7HMYtN8c1KmwpwHFBwTeFZrg9XZa+DFTitWOW5iTAG7tyCUPsCCyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, "node_modules/@babel/plugin-transform-typescript": { "version": "7.28.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.28.0.tgz", "integrity": "sha512-4AEiDEBPIZvLQaWlc9liCavE0xRM0dNca41WtBeM3jgFptfUOSG9z0uteLhq6+3rq+WB6jIvUwKDTpXEHPJ2Vg==", + "dev": true, "license": "MIT", "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", @@ -590,6 +650,26 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/preset-typescript": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.27.1.tgz", + "integrity": "sha512-l7WfQfX0WK4M0v2RudjuQK4u99BS6yLHYEmdtVPP7lKV013zr9DygFuWNlnbvQ9LR+LS0Egz/XAvGx5U9MX0fQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-validator-option": "^7.27.1", + "@babel/plugin-syntax-jsx": "^7.27.1", + "@babel/plugin-transform-modules-commonjs": "^7.27.1", + "@babel/plugin-transform-typescript": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, "node_modules/@babel/runtime": { "version": "7.28.4", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.4.tgz", @@ -603,6 +683,7 @@ "version": "7.27.2", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz", "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==", + "dev": true, "license": "MIT", "dependencies": { "@babel/code-frame": "^7.27.1", @@ -617,6 +698,7 @@ "version": "7.28.4", "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.4.tgz", "integrity": "sha512-YEzuboP2qvQavAcjgQNVgsvHIDv6ZpwXvcvjmyySP2DIMuByS/6ioU5G9pYrWHM6T2YDfc7xga9iNzYOs12CFQ==", + "dev": true, "license": "MIT", "dependencies": { "@babel/code-frame": "^7.27.1", @@ -635,6 +717,7 @@ "version": "7.28.4", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.4.tgz", "integrity": "sha512-bkFqkLhh3pMBUQQkpVgWDWq/lqzc2678eUyDlTBhRqhCHFguYYGM0Efga7tYk4TogG/3x0EEl66/OQ+WGbWB/Q==", + "devOptional": true, "license": "MIT", "dependencies": { "@babel/helper-string-parser": "^7.27.1", @@ -654,6 +737,7 @@ "version": "1.51.0", "resolved": "https://registry.npmjs.org/@dotenvx/dotenvx/-/dotenvx-1.51.0.tgz", "integrity": "sha512-CbMGzyOYSyFF7d4uaeYwO9gpSBzLTnMmSmTVpCZjvpJFV69qYbjYPpzNnCz1mb2wIvEhjWjRwQWuBzTO0jITww==", + "dev": true, "license": "BSD-3-Clause", "dependencies": { "commander": "^11.1.0", @@ -677,6 +761,7 @@ "version": "11.1.0", "resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz", "integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==", + "dev": true, "license": "MIT", "engines": { "node": ">=16" @@ -686,6 +771,7 @@ "version": "5.1.1", "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, "license": "MIT", "dependencies": { "cross-spawn": "^7.0.3", @@ -709,6 +795,7 @@ "version": "6.5.0", "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, "license": "MIT", "engines": { "node": ">=12.0.0" @@ -726,6 +813,7 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true, "license": "MIT", "engines": { "node": ">=10" @@ -738,6 +826,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true, "license": "Apache-2.0", "engines": { "node": ">=10.17.0" @@ -747,6 +836,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -759,6 +849,7 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", + "dev": true, "license": "ISC", "engines": { "node": ">=16" @@ -768,6 +859,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -777,6 +869,7 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, "license": "MIT", "dependencies": { "path-key": "^3.0.0" @@ -789,6 +882,7 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, "license": "MIT", "dependencies": { "mimic-fn": "^2.1.0" @@ -804,6 +898,7 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "dev": true, "license": "MIT", "engines": { "node": ">=12" @@ -816,12 +911,14 @@ "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true, "license": "ISC" }, "node_modules/@dotenvx/dotenvx/node_modules/strip-final-newline": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -831,6 +928,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz", "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==", + "dev": true, "license": "ISC", "dependencies": { "isexe": "^3.1.1" @@ -846,6 +944,7 @@ "version": "0.2.4", "resolved": "https://registry.npmjs.org/@ecies/ciphers/-/ciphers-0.2.4.tgz", "integrity": "sha512-t+iX+Wf5nRKyNzk8dviW3Ikb/280+aEJAnw9YXvCp2tYGPSkMki+NRY+8aNLmVFv3eNtMdvViPNOPxS8SZNP+w==", + "dev": true, "license": "MIT", "engines": { "bun": ">=1", @@ -3265,6 +3364,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/@inquirer/ansi/-/ansi-1.0.1.tgz", "integrity": "sha512-yqq0aJW/5XPhi5xOAL1xRCpe1eh8UFVgYFpFsjEqmIR8rKLyP+HINvFXwUaxYICflJrVlxnp7lLN6As735kVpw==", + "dev": true, "license": "MIT", "engines": { "node": ">=18" @@ -3274,6 +3374,7 @@ "version": "5.1.19", "resolved": "https://registry.npmjs.org/@inquirer/confirm/-/confirm-5.1.19.tgz", "integrity": "sha512-wQNz9cfcxrtEnUyG5PndC8g3gZ7lGDBzmWiXZkX8ot3vfZ+/BLjR8EvyGX4YzQLeVqtAlY/YScZpW7CW8qMoDQ==", + "dev": true, "license": "MIT", "dependencies": { "@inquirer/core": "^10.3.0", @@ -3295,6 +3396,7 @@ "version": "10.3.0", "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-10.3.0.tgz", "integrity": "sha512-Uv2aPPPSK5jeCplQmQ9xadnFx2Zhj9b5Dj7bU6ZeCdDNNY11nhYy4btcSdtDguHqCT2h5oNeQTcUNSGGLA7NTA==", + "dev": true, "license": "MIT", "dependencies": { "@inquirer/ansi": "^1.0.1", @@ -3322,6 +3424,7 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -3337,12 +3440,14 @@ "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, "license": "MIT" }, "node_modules/@inquirer/core/node_modules/is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -3352,6 +3457,7 @@ "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", @@ -3366,6 +3472,7 @@ "version": "6.2.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", @@ -3380,6 +3487,7 @@ "version": "1.0.14", "resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-1.0.14.tgz", "integrity": "sha512-DbFgdt+9/OZYFM+19dbpXOSeAstPy884FPy1KjDu4anWwymZeOYhMY1mdFri172htv6mvc/uvIAAi7b7tvjJBQ==", + "dev": true, "license": "MIT", "engines": { "node": ">=18" @@ -3389,6 +3497,7 @@ "version": "3.0.9", "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-3.0.9.tgz", "integrity": "sha512-QPaNt/nmE2bLGQa9b7wwyRJoLZ7pN6rcyXvzU0YCmivmJyq1BVo94G98tStRWkoD1RgDX5C+dPlhhHzNdu/W/w==", + "dev": true, "license": "MIT", "engines": { "node": ">=18" @@ -3443,6 +3552,7 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/@isaacs/balanced-match/-/balanced-match-4.0.1.tgz", "integrity": "sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==", + "dev": true, "license": "MIT", "engines": { "node": "20 || >=22" @@ -3452,6 +3562,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/@isaacs/brace-expansion/-/brace-expansion-5.0.0.tgz", "integrity": "sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==", + "dev": true, "license": "MIT", "dependencies": { "@isaacs/balanced-match": "^4.0.1" @@ -3776,6 +3887,7 @@ "version": "1.20.1", "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.20.1.tgz", "integrity": "sha512-j/P+yuxXfgxb+mW7OEoRCM3G47zCTDqUPivJo/VzpjbG8I9csTXtOprCf5FfOfHK4whOJny0aHuBEON+kS7CCA==", + "dev": true, "license": "MIT", "dependencies": { "ajv": "^6.12.6", @@ -3799,6 +3911,7 @@ "version": "3.25.76", "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", + "dev": true, "license": "MIT", "funding": { "url": "https://github.com/sponsors/colinhacks" @@ -3808,6 +3921,7 @@ "version": "3.24.6", "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.24.6.tgz", "integrity": "sha512-h/z3PKvcTcTetyjl1fkj79MHNEjm+HpD6NXheWjzOekY7kV+lwDYnHw+ivHkijnCSMz1yJaWBD9vu/Fcmk+vEg==", + "dev": true, "license": "ISC", "peerDependencies": { "zod": "^3.24.1" @@ -3817,6 +3931,7 @@ "version": "0.40.0", "resolved": "https://registry.npmjs.org/@mswjs/interceptors/-/interceptors-0.40.0.tgz", "integrity": "sha512-EFd6cVbHsgLa6wa4RljGj6Wk75qoHxUSyc5asLyyPSyuhIcdS2Q3Phw6ImS1q+CkALthJRShiYfKANcQMuMqsQ==", + "dev": true, "license": "MIT", "dependencies": { "@open-draft/deferred-promise": "^2.2.0", @@ -4003,6 +4118,7 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/@noble/ciphers/-/ciphers-1.3.0.tgz", "integrity": "sha512-2I0gnIVPtfnMw9ee9h1dJG7tp81+8Ob3OJb3Mv37rx5L40/b0i7djjCVvGOVqc9AEIQyvyu1i6ypKdFw8R8gQw==", + "dev": true, "license": "MIT", "engines": { "node": "^14.21.3 || >=16" @@ -4015,6 +4131,7 @@ "version": "1.9.7", "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.9.7.tgz", "integrity": "sha512-gbKGcRUYIjA3/zCCNaWDciTMFI0dCkvou3TL8Zmy5Nc7sJ47a0jtOeZoTaMxkuqRo9cRhjOdZJXegxYE5FN/xw==", + "dev": true, "license": "MIT", "dependencies": { "@noble/hashes": "1.8.0" @@ -4030,6 +4147,7 @@ "version": "1.8.0", "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz", "integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==", + "dev": true, "license": "MIT", "engines": { "node": "^14.21.3 || >=16" @@ -4042,6 +4160,7 @@ "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, "license": "MIT", "dependencies": { "@nodelib/fs.stat": "2.0.5", @@ -4055,6 +4174,7 @@ "version": "2.0.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, "license": "MIT", "engines": { "node": ">= 8" @@ -4064,6 +4184,7 @@ "version": "1.2.8", "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, "license": "MIT", "dependencies": { "@nodelib/fs.scandir": "2.1.5", @@ -4087,12 +4208,14 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/@open-draft/deferred-promise/-/deferred-promise-2.2.0.tgz", "integrity": "sha512-CecwLWx3rhxVQF6V4bAgPS5t+So2sTbPgAzafKkVizyi7tlwpcFpdFqq+wqF2OwNBmqFuu6tOyouTuxgpMfzmA==", + "dev": true, "license": "MIT" }, "node_modules/@open-draft/logger": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/@open-draft/logger/-/logger-0.3.0.tgz", "integrity": "sha512-X2g45fzhxH238HKO4xbSr7+wBS8Fvw6ixhTDuvLd5mqh6bJJCFAPwU9mPDxbcrRtfxv4u5IHCEH77BmxvXmmxQ==", + "dev": true, "license": "MIT", "dependencies": { "is-node-process": "^1.2.0", @@ -4103,6 +4226,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/@open-draft/until/-/until-2.1.0.tgz", "integrity": "sha512-U69T3ItWHvLwGg5eJ0n3I62nWuE6ilHlmz7zM0npLBRvPRd7e6NYmg54vvRtP5mZG7kZqZCFVdsTWo7BPtBujg==", + "dev": true, "license": "MIT" }, "node_modules/@opentelemetry/api": { @@ -4137,13 +4261,13 @@ } }, "node_modules/@playwright/test": { - "version": "1.53.2", - "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.53.2.tgz", - "integrity": "sha512-tEB2U5z74ebBeyfGNZ3Jfg29AnW+5HlWhvHtb/Mqco9pFdZU1ZLNdVb2UtB5CvmiilNr2ZfVH/qMmAROG/XTzw==", + "version": "1.56.1", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.56.1.tgz", + "integrity": "sha512-vSMYtL/zOcFpvJCW71Q/OEGQb7KYBPAdKh35WNSkaZA75JlAO8ED8UN6GUNTm3drWomcbcqRPFqQbLae8yBTdg==", "devOptional": true, "license": "Apache-2.0", "dependencies": { - "playwright": "1.53.2" + "playwright": "1.56.1" }, "bin": { "playwright": "cli.js" @@ -7750,12 +7874,14 @@ "version": "0.4.1", "resolved": "https://registry.npmjs.org/@sec-ant/readable-stream/-/readable-stream-0.4.1.tgz", "integrity": "sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==", + "dev": true, "license": "MIT" }, "node_modules/@sindresorhus/merge-streams": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-4.0.0.tgz", "integrity": "sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==", + "dev": true, "license": "MIT", "engines": { "node": ">=18" @@ -8153,6 +8279,7 @@ "version": "0.27.0", "resolved": "https://registry.npmjs.org/@ts-morph/common/-/common-0.27.0.tgz", "integrity": "sha512-Wf29UqxWDpc+i61k3oIOzcUfQt79PIT9y/MWfAGlrkjg6lBC1hwDECLXPVJAhWjiGbfBCxZd65F/LIZF3+jeJQ==", + "dev": true, "license": "MIT", "dependencies": { "fast-glob": "^3.3.3", @@ -8164,6 +8291,7 @@ "version": "3.3.3", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "dev": true, "license": "MIT", "dependencies": { "@nodelib/fs.stat": "^2.0.2", @@ -8180,6 +8308,7 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, "license": "ISC", "dependencies": { "is-glob": "^4.0.1" @@ -8192,6 +8321,7 @@ "version": "10.0.3", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.3.tgz", "integrity": "sha512-IPZ167aShDZZUMdRk66cyQAW3qr0WzbHkPdMYa8bzZhlHhO3jALbKdxcaak7W9FfT2rZNpQuUu4Od7ILEpXSaw==", + "dev": true, "license": "ISC", "dependencies": { "@isaacs/brace-expansion": "^5.0.0" @@ -8566,7 +8696,7 @@ "version": "20.5.7", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.5.7.tgz", "integrity": "sha512-dP7f3LdZIysZnmvP3ANJYTSwg+wLLl8p7RqniVlV7j+oXSXAbt9h0WIBFmJy5inWZoX9wZN6eXx+YXd9Rh3RBA==", - "devOptional": true, + "dev": true, "license": "MIT" }, "node_modules/@types/react": { @@ -8598,6 +8728,7 @@ "version": "2.0.6", "resolved": "https://registry.npmjs.org/@types/statuses/-/statuses-2.0.6.tgz", "integrity": "sha512-xMAgYwceFhRA2zY+XbEA7mxYbA093wdiW8Vu6gZPGWy9cmOyU9XesH1tNcEWsKFd5Vzrqx5T3D38PWx1FIIXkA==", + "dev": true, "license": "MIT" }, "node_modules/@types/topojson-client": { @@ -9105,6 +9236,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz", "integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==", + "dev": true, "license": "MIT", "dependencies": { "mime-types": "^3.0.0", @@ -9141,6 +9273,7 @@ "version": "7.1.4", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", + "dev": true, "license": "MIT", "engines": { "node": ">= 14" @@ -9168,6 +9301,7 @@ "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", @@ -9210,6 +9344,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -9231,6 +9366,7 @@ "version": "4.2.0", "resolved": "https://registry.npmjs.org/ansis/-/ansis-4.2.0.tgz", "integrity": "sha512-HqZ5rWlFjGiV0tDm3UxxgNRqsOTniqoKZu0pIAfh7TZQMGuZK+hH0drySty0si0QXj1ieop4+SkSfPZBPPkHig==", + "dev": true, "license": "ISC", "engines": { "node": ">=14" @@ -9438,6 +9574,7 @@ "version": "0.16.1", "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.16.1.tgz", "integrity": "sha512-6t10qk83GOG8p0vKmaCr8eiilZwO171AvbROMtvvNiwrTly62t+7XkA8RdIIVbpMhCASAsxgAzdRSwh6nw/5Dg==", + "dev": true, "license": "MIT", "dependencies": { "tslib": "^2.0.1" @@ -9588,6 +9725,7 @@ "version": "2.8.19", "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.8.19.tgz", "integrity": "sha512-zoKGUdu6vb2jd3YOq0nnhEDQVbPcHhco3UImJrv5dSkvxTc2pl2WjOPsjZXDwPDSl5eghIMuY3R6J9NDKF3KcQ==", + "dev": true, "license": "Apache-2.0", "bin": { "baseline-browser-mapping": "dist/cli.js" @@ -9597,6 +9735,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.0.tgz", "integrity": "sha512-02qvAaxv8tp7fBa/mw1ga98OGm+eCbqzJOKoRt70sLmfEEi+jyBYVTDGfCL/k06/4EMk/z01gCe7HoCH/f2LTg==", + "dev": true, "license": "MIT", "dependencies": { "bytes": "^3.1.2", @@ -9627,6 +9766,7 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, "license": "MIT", "dependencies": { "fill-range": "^7.1.1" @@ -9639,6 +9779,7 @@ "version": "4.26.3", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.26.3.tgz", "integrity": "sha512-lAUU+02RFBuCKQPj/P6NgjlbCnLBMp4UtgTx7vNHd3XSIJF87s9a5rA3aH2yw3GS9DqZAUbOtZdCCiZeVRqt0w==", + "dev": true, "funding": [ { "type": "opencollective", @@ -9672,6 +9813,7 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.8" @@ -9700,6 +9842,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "dev": true, "license": "MIT", "dependencies": { "es-errors": "^1.3.0", @@ -9713,6 +9856,7 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "dev": true, "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.2", @@ -9729,6 +9873,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -9872,6 +10017,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-5.0.0.tgz", "integrity": "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==", + "dev": true, "license": "MIT", "dependencies": { "restore-cursor": "^5.0.0" @@ -9887,6 +10033,7 @@ "version": "2.9.2", "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz", "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==", + "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -9916,6 +10063,7 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz", "integrity": "sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==", + "dev": true, "license": "ISC", "engines": { "node": ">= 12" @@ -9931,6 +10079,7 @@ "version": "8.0.1", "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, "license": "ISC", "dependencies": { "string-width": "^4.2.0", @@ -9945,6 +10094,7 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -9960,12 +10110,14 @@ "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, "license": "MIT" }, "node_modules/cliui/node_modules/is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -9975,6 +10127,7 @@ "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", @@ -9989,6 +10142,7 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", @@ -10015,6 +10169,7 @@ "version": "13.0.3", "resolved": "https://registry.npmjs.org/code-block-writer/-/code-block-writer-13.0.3.tgz", "integrity": "sha512-Oofo0pq3IKnsFtuHqSF7TqBfr71aeyZDVJ0HpmqB7FBM2qEigL0iPONSCZSO9pE9dZTAxANe5XHG9Uy0YMv8cg==", + "dev": true, "license": "MIT" }, "node_modules/color": { @@ -10116,6 +10271,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.0.tgz", "integrity": "sha512-Au9nRL8VNUut/XSzbQA38+M78dzP4D+eqg3gfJHMIHHYa3bg067xj1KxMUWj+VULbiZMowKngFFbKczUrNJ1mg==", + "dev": true, "license": "MIT", "dependencies": { "safe-buffer": "5.2.1" @@ -10128,6 +10284,7 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.6" @@ -10137,12 +10294,14 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, "license": "MIT" }, "node_modules/cookie": { "version": "0.7.2", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.6" @@ -10152,6 +10311,7 @@ "version": "1.2.2", "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz", "integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==", + "dev": true, "license": "MIT", "engines": { "node": ">=6.6.0" @@ -10161,6 +10321,7 @@ "version": "2.8.5", "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "dev": true, "license": "MIT", "dependencies": { "object-assign": "^4", @@ -10174,6 +10335,7 @@ "version": "9.0.0", "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.0.tgz", "integrity": "sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==", + "dev": true, "license": "MIT", "dependencies": { "env-paths": "^2.2.1", @@ -10200,6 +10362,7 @@ "version": "7.0.6", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, "license": "MIT", "dependencies": { "path-key": "^3.1.0", @@ -10640,6 +10803,7 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==", + "dev": true, "license": "MIT", "engines": { "node": ">= 12" @@ -10764,6 +10928,7 @@ "version": "1.7.0", "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.7.0.tgz", "integrity": "sha512-HGFtf8yhuhGhqO07SV79tRp+br4MnbdjeVxotpn1QBl30pcLLCQjX5b2295ll0fv8RKDKsmWYrl05usHM9CewQ==", + "dev": true, "license": "MIT", "peerDependencies": { "babel-plugin-macros": "^3.1.0" @@ -10839,6 +11004,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.8" @@ -10885,6 +11051,7 @@ "version": "8.0.2", "resolved": "https://registry.npmjs.org/diff/-/diff-8.0.2.tgz", "integrity": "sha512-sSuxWU5j5SR9QQji/o2qMvqRNYRDOcBTgsJ/DeCf4iSN4gW+gNMXM7wFIP+fdXZxoNiAnHUTGjCr+TSWXdRDKg==", + "dev": true, "license": "BSD-3-Clause", "engines": { "node": ">=0.3.1" @@ -10930,6 +11097,7 @@ "version": "17.2.3", "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.2.3.tgz", "integrity": "sha512-JVUnt+DUIzu87TABbhPmNfVdBDt18BLOWjMUFJMSi/Qqg7NTYtabbvSNJGOJ7afbRuv9D/lngizHtP7QyLQ+9w==", + "dev": true, "license": "BSD-2-Clause", "engines": { "node": ">=12" @@ -10942,6 +11110,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dev": true, "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.1", @@ -10956,6 +11125,7 @@ "version": "0.4.16", "resolved": "https://registry.npmjs.org/eciesjs/-/eciesjs-0.4.16.tgz", "integrity": "sha512-dS5cbA9rA2VR4Ybuvhg6jvdmp46ubLn3E+px8cG/35aEDNclrqoCjg6mt0HYZ/M+OoESS3jSkCrqk1kWAEhWAw==", + "dev": true, "license": "MIT", "dependencies": { "@ecies/ciphers": "^0.2.4", @@ -10973,12 +11143,14 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "dev": true, "license": "MIT" }, "node_modules/electron-to-chromium": { "version": "1.5.238", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.238.tgz", "integrity": "sha512-khBdc+w/Gv+cS8e/Pbnaw/FXcBUeKrRVik9IxfXtgREOWyJhR4tj43n3amkVogJ/yeQUqzkrZcFhtIxIdqmmcQ==", + "dev": true, "license": "ISC" }, "node_modules/emoji-regex": { @@ -10992,6 +11164,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.8" @@ -11023,6 +11196,7 @@ "version": "2.2.1", "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -11045,6 +11219,7 @@ "version": "1.3.4", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.4.tgz", "integrity": "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==", + "dev": true, "license": "MIT", "dependencies": { "is-arrayish": "^0.2.1" @@ -11123,6 +11298,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -11132,6 +11308,7 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -11169,6 +11346,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "dev": true, "license": "MIT", "dependencies": { "es-errors": "^1.3.0" @@ -11228,6 +11406,7 @@ "version": "3.2.0", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -11237,6 +11416,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "dev": true, "license": "MIT" }, "node_modules/escape-string-regexp": { @@ -11973,6 +12153,7 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, "license": "BSD-2-Clause", "bin": { "esparse": "bin/esparse.js", @@ -12042,6 +12223,7 @@ "version": "1.8.1", "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.6" @@ -12058,6 +12240,7 @@ "version": "3.0.7", "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-3.0.7.tgz", "integrity": "sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA==", + "dev": true, "license": "MIT", "dependencies": { "eventsource-parser": "^3.0.1" @@ -12103,6 +12286,7 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/express/-/express-5.1.0.tgz", "integrity": "sha512-DT9ck5YIRU+8GYzzU5kT3eHGA5iL+1Zd0EutOmTE9Dtk+Tvuzd23VBU+ec7HPNSTxXYO55gPV/hq4pSBJDjFpA==", + "dev": true, "license": "MIT", "dependencies": { "accepts": "^2.0.0", @@ -12145,6 +12329,7 @@ "version": "7.5.1", "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-7.5.1.tgz", "integrity": "sha512-7iN8iPMDzOMHPUYllBEsQdWVB6fPDMPqwjBaFrgr4Jgr/+okjvzAy+UHlYYL/Vs0OsOrMkwS6PJDkFlJwoxUnw==", + "dev": true, "license": "MIT", "engines": { "node": ">= 16" @@ -12166,6 +12351,7 @@ "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, "license": "MIT" }, "node_modules/fast-diff": { @@ -12218,6 +12404,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true, "license": "MIT" }, "node_modules/fast-levenshtein": { @@ -12231,6 +12418,7 @@ "version": "1.19.1", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", + "dev": true, "license": "ISC", "dependencies": { "reusify": "^1.0.4" @@ -12240,6 +12428,7 @@ "version": "3.2.0", "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==", + "dev": true, "funding": [ { "type": "github", @@ -12263,6 +12452,7 @@ "version": "6.1.0", "resolved": "https://registry.npmjs.org/figures/-/figures-6.1.0.tgz", "integrity": "sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg==", + "dev": true, "license": "MIT", "dependencies": { "is-unicode-supported": "^2.0.0" @@ -12291,6 +12481,7 @@ "version": "7.1.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, "license": "MIT", "dependencies": { "to-regex-range": "^5.0.1" @@ -12303,6 +12494,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.0.tgz", "integrity": "sha512-/t88Ty3d5JWQbWYgaOGCCYfXRwV1+be02WqYYlL6h0lEiUAMPM8o8qKGO01YIkOHzka2up08wvgYD0mDiI+q3Q==", + "dev": true, "license": "MIT", "dependencies": { "debug": "^4.4.0", @@ -12384,6 +12576,7 @@ "version": "4.0.10", "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", + "dev": true, "license": "MIT", "dependencies": { "fetch-blob": "^3.1.2" @@ -12396,6 +12589,7 @@ "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.6" @@ -12446,6 +12640,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz", "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.8" @@ -12455,6 +12650,7 @@ "version": "11.3.2", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.2.tgz", "integrity": "sha512-Xr9F6z6up6Ws+NjzMCZc6WXg2YFRlrLP9NQDO3VQrWrfiojdhS56TzueT88ze0uBdCTwEIhQ3ptnmKeWGFAe0A==", + "dev": true, "license": "MIT", "dependencies": { "graceful-fs": "^4.2.0", @@ -12491,6 +12687,7 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" @@ -12531,12 +12728,14 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/fuzzysort/-/fuzzysort-3.1.0.tgz", "integrity": "sha512-sR9BNCjBg6LNgwvxlBd0sBABvQitkLzoVY9MYYROQVX/FvfJ4Mai9LsGhDgd8qYdds0bY77VzYd5iuB+v5rwQQ==", + "dev": true, "license": "MIT" }, "node_modules/fzf": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/fzf/-/fzf-0.5.2.tgz", "integrity": "sha512-Tt4kuxLXFKHy8KT40zwsUPUkg1CrsgY25FxA2U/j/0WgEDCk3ddc/zLTCCcbSHX9FcKtLuVaDGtGE/STWC+j3Q==", + "dev": true, "license": "BSD-3-Clause" }, "node_modules/generator-function": { @@ -12553,6 +12752,7 @@ "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, "license": "MIT", "engines": { "node": ">=6.9.0" @@ -12562,6 +12762,7 @@ "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, "license": "ISC", "engines": { "node": "6.* || 8.* || >= 10.*" @@ -12571,6 +12772,7 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.4.0.tgz", "integrity": "sha512-QZjmEOC+IT1uk6Rx0sX22V6uHWVwbdbxf1faPqJ1QhLdGgsRGCZoyaQBm/piRdJy/D2um6hM1UP7ZEeQ4EkP+Q==", + "dev": true, "license": "MIT", "engines": { "node": ">=18" @@ -12583,6 +12785,7 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "dev": true, "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.2", @@ -12616,6 +12819,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/get-own-enumerable-keys/-/get-own-enumerable-keys-1.0.0.tgz", "integrity": "sha512-PKsK2FSrQCyxcGHsGrLDcK0lx+0Ke+6e8KFFozA9/fIQLhQzPaRvJFdcz7+Axg3jUH/Mq+NI4xa5u/UT2tQskA==", + "dev": true, "license": "MIT", "engines": { "node": ">=14.16" @@ -12628,6 +12832,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dev": true, "license": "MIT", "dependencies": { "dunder-proto": "^1.0.1", @@ -12798,6 +13003,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -12823,6 +13029,7 @@ "version": "16.11.0", "resolved": "https://registry.npmjs.org/graphql/-/graphql-16.11.0.tgz", "integrity": "sha512-mS1lbMsxgQj6hge1XZ6p7GPhbrtFwUFYi3wRzXAC/FmYnyXMTvvI3td3rjmQ2u8ewXueaSvRPWaEcgVVOT9Jnw==", + "dev": true, "license": "MIT", "engines": { "node": "^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0" @@ -12883,6 +13090,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -12911,6 +13119,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, "license": "MIT", "dependencies": { "function-bind": "^1.1.2" @@ -12963,6 +13172,7 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/headers-polyfill/-/headers-polyfill-4.0.3.tgz", "integrity": "sha512-IScLbePpkvO846sIwOtOTDjutRMWdXdJmXdMvk6gCBHxFO8d+QKOQedyZSxFTTFYRSmlgSTDtXqqq4pcenBXLQ==", + "dev": true, "license": "MIT" }, "node_modules/html-url-attributes": { @@ -12979,6 +13189,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "dev": true, "license": "MIT", "dependencies": { "depd": "2.0.0", @@ -12995,6 +13206,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.8" @@ -13004,6 +13216,7 @@ "version": "7.0.6", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", + "dev": true, "license": "MIT", "dependencies": { "agent-base": "^7.1.2", @@ -13055,6 +13268,7 @@ "version": "5.3.2", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, "license": "MIT", "engines": { "node": ">= 4" @@ -13064,6 +13278,7 @@ "version": "3.3.1", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", + "dev": true, "license": "MIT", "dependencies": { "parent-module": "^1.0.0", @@ -13102,6 +13317,7 @@ "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true, "license": "ISC" }, "node_modules/inline-style-parser": { @@ -13160,6 +13376,7 @@ "version": "1.9.1", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.10" @@ -13211,6 +13428,7 @@ "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true, "license": "MIT" }, "node_modules/is-async-function": { @@ -13354,6 +13572,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -13412,6 +13631,7 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, "license": "MIT", "dependencies": { "is-extglob": "^2.1.1" @@ -13434,6 +13654,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-2.0.0.tgz", "integrity": "sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==", + "dev": true, "license": "MIT", "engines": { "node": ">=12" @@ -13472,12 +13693,14 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/is-node-process/-/is-node-process-1.2.0.tgz", "integrity": "sha512-Vg4o6/fqPxIjtxgUH5QLJhwZ7gW5diGCVlXpuUfELC62CuxM1iHcRe51f2W1FDy04Ai4KJkagKjx3XaqyfRKXw==", + "dev": true, "license": "MIT" }, "node_modules/is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, "license": "MIT", "engines": { "node": ">=0.12.0" @@ -13504,6 +13727,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-3.0.0.tgz", "integrity": "sha512-IlsXEHOjtKhpN8r/tRFj2nDyTmHvcfNeu/nrRIcXE17ROeatXchkojffa1SpdqW4cr/Fj6QkEf/Gn4zf6KKvEQ==", + "dev": true, "license": "MIT", "engines": { "node": ">=12" @@ -13538,6 +13762,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz", "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==", + "dev": true, "license": "MIT" }, "node_modules/is-regex": { @@ -13563,6 +13788,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-3.1.0.tgz", "integrity": "sha512-rbku49cWloU5bSMI+zaRaXdQHXnthP6DZ/vLnfdSKyL4zUzuWnomtOEiZZOd+ioQ+avFo/qau3KPTc7Fjy1uPA==", + "dev": true, "license": "MIT", "engines": { "node": ">=12" @@ -13668,6 +13894,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-2.1.0.tgz", "integrity": "sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==", + "dev": true, "license": "MIT", "engines": { "node": ">=18" @@ -13733,6 +13960,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, "license": "ISC" }, "node_modules/iterator.prototype": { @@ -13802,6 +14030,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "dev": true, "license": "MIT", "bin": { "jsesc": "bin/jsesc" @@ -13821,6 +14050,7 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true, "license": "MIT" }, "node_modules/json-schema": { @@ -13833,6 +14063,7 @@ "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, "license": "MIT" }, "node_modules/json-stable-stringify-without-jsonify": { @@ -13846,6 +14077,7 @@ "version": "2.2.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, "license": "MIT", "bin": { "json5": "lib/cli.js" @@ -13858,6 +14090,7 @@ "version": "6.2.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz", "integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==", + "dev": true, "license": "MIT", "dependencies": { "universalify": "^2.0.0" @@ -13905,6 +14138,7 @@ "version": "4.1.5", "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==", + "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -14237,6 +14471,7 @@ "version": "1.2.4", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true, "license": "MIT" }, "node_modules/lint-staged": { @@ -14352,6 +14587,7 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-6.0.0.tgz", "integrity": "sha512-i24m8rpwhmPIS4zscNzK6MSEhk0DUWa/8iYQWxhffV8jkI4Phvs3F+quL5xvS0gdQR0FyTCMMH33Y78dDTzzIw==", + "dev": true, "license": "MIT", "dependencies": { "chalk": "^5.3.0", @@ -14368,6 +14604,7 @@ "version": "5.6.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", + "dev": true, "license": "MIT", "engines": { "node": "^12.17.0 || ^14.13 || >=16.0.0" @@ -14380,6 +14617,7 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-1.3.0.tgz", "integrity": "sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==", + "dev": true, "license": "MIT", "engines": { "node": ">=12" @@ -14509,6 +14747,7 @@ "version": "5.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, "license": "ISC", "dependencies": { "yallist": "^3.0.2" @@ -14548,6 +14787,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -14710,6 +14950,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz", "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.8" @@ -14719,6 +14960,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz", "integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==", + "dev": true, "license": "MIT", "engines": { "node": ">=18" @@ -14731,12 +14973,14 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true, "license": "MIT" }, "node_modules/merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, "license": "MIT", "engines": { "node": ">= 8" @@ -15188,6 +15432,7 @@ "version": "4.0.8", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dev": true, "license": "MIT", "dependencies": { "braces": "^3.0.3", @@ -15201,6 +15446,7 @@ "version": "1.54.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.6" @@ -15210,6 +15456,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.1.tgz", "integrity": "sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==", + "dev": true, "license": "MIT", "dependencies": { "mime-db": "^1.54.0" @@ -15235,6 +15482,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/mimic-function/-/mimic-function-5.0.1.tgz", "integrity": "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==", + "dev": true, "license": "MIT", "engines": { "node": ">=18" @@ -15263,6 +15511,7 @@ "version": "1.2.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" @@ -15314,6 +15563,7 @@ "version": "2.11.6", "resolved": "https://registry.npmjs.org/msw/-/msw-2.11.6.tgz", "integrity": "sha512-MCYMykvmiYScyUm7I6y0VCxpNq1rgd5v7kG8ks5dKtvmxRUUPjribX6mUoUNBbM5/3PhUyoelEWiKXGOz84c+w==", + "dev": true, "hasInstallScript": true, "license": "MIT", "dependencies": { @@ -15358,6 +15608,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.0.2.tgz", "integrity": "sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==", + "dev": true, "license": "MIT", "engines": { "node": ">=18" @@ -15367,6 +15618,7 @@ "version": "4.41.0", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz", "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==", + "dev": true, "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=16" @@ -15388,6 +15640,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-2.0.0.tgz", "integrity": "sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==", + "dev": true, "license": "ISC", "engines": { "node": "^18.17.0 || >=20.5.0" @@ -15438,6 +15691,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.6" @@ -15979,6 +16233,7 @@ "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", "deprecated": "Use your platform's native DOMException instead", + "dev": true, "funding": [ { "type": "github", @@ -15998,6 +16253,7 @@ "version": "3.3.2", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz", "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==", + "dev": true, "license": "MIT", "dependencies": { "data-uri-to-buffer": "^4.0.0", @@ -16016,6 +16272,7 @@ "version": "2.0.26", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.26.tgz", "integrity": "sha512-S2M9YimhSjBSvYnlr5/+umAnPHE++ODwt5e2Ij6FoX45HA/s4vHdkDx1eax2pAPeAOqu4s9b7ppahsyEFdVqQA==", + "dev": true, "license": "MIT" }, "node_modules/normalize-range": { @@ -16079,6 +16336,7 @@ "version": "1.13.4", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -16101,6 +16359,7 @@ "version": "1.1.33", "resolved": "https://registry.npmjs.org/object-treeify/-/object-treeify-1.1.33.tgz", "integrity": "sha512-EFVjAYfzWqWsBMRHPMAXLCDIJnpMhdWAqR7xG6M6a2cs6PMFpl/+Z20w9zDW4vkxOFfddegBKq9Rehd0bxWE7A==", + "dev": true, "license": "MIT", "engines": { "node": ">= 10" @@ -16200,6 +16459,7 @@ "version": "2.4.1", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dev": true, "license": "MIT", "dependencies": { "ee-first": "1.1.1" @@ -16212,6 +16472,7 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, "license": "ISC", "dependencies": { "wrappy": "1" @@ -16255,6 +16516,7 @@ "version": "8.2.0", "resolved": "https://registry.npmjs.org/ora/-/ora-8.2.0.tgz", "integrity": "sha512-weP+BZ8MVNnlCm8c0Qdc1WSWq4Qn7I+9CJGm7Qali6g44e/PUzbjNqJX5NJ9ljlNMosfJvg1fKEGILklK9cwnw==", + "dev": true, "license": "MIT", "dependencies": { "chalk": "^5.3.0", @@ -16278,6 +16540,7 @@ "version": "6.2.2", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "dev": true, "license": "MIT", "engines": { "node": ">=12" @@ -16290,6 +16553,7 @@ "version": "5.6.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", + "dev": true, "license": "MIT", "engines": { "node": "^12.17.0 || ^14.13 || >=16.0.0" @@ -16302,6 +16566,7 @@ "version": "7.1.2", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", + "dev": true, "license": "MIT", "dependencies": { "ansi-regex": "^6.0.1" @@ -16317,6 +16582,7 @@ "version": "1.4.3", "resolved": "https://registry.npmjs.org/outvariant/-/outvariant-1.4.3.tgz", "integrity": "sha512-+Sl2UErvtsoajRDKCE5/dBz4DIvHXQQnAxtQTF04OJxY0+DyZXSo5P5Bb7XYWOh81syohlYL24hbDwxedPUJCA==", + "dev": true, "license": "MIT" }, "node_modules/own-keys": { @@ -16429,12 +16695,14 @@ "version": "1.5.0", "resolved": "https://registry.npmjs.org/package-manager-detector/-/package-manager-detector-1.5.0.tgz", "integrity": "sha512-uBj69dVlYe/+wxj8JOpr97XfsxH/eumMt6HqjNTmJDf/6NO9s+0uxeOneIz3AsPt2m6y9PqzDzd3ATcU17MNfw==", + "dev": true, "license": "MIT" }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, "license": "MIT", "dependencies": { "callsites": "^3.0.0" @@ -16472,6 +16740,7 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, "license": "MIT", "dependencies": { "@babel/code-frame": "^7.0.0", @@ -16490,6 +16759,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-4.0.0.tgz", "integrity": "sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw==", + "dev": true, "license": "MIT", "engines": { "node": ">=18" @@ -16502,6 +16772,7 @@ "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.8" @@ -16511,6 +16782,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==", + "dev": true, "license": "MIT" }, "node_modules/path-exists": { @@ -16537,6 +16809,7 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -16553,6 +16826,7 @@ "version": "6.3.0", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.3.0.tgz", "integrity": "sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==", + "dev": true, "license": "MIT" }, "node_modules/path-type": { @@ -16575,6 +16849,7 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, "license": "MIT", "engines": { "node": ">=8.6" @@ -16600,19 +16875,20 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/pkce-challenge/-/pkce-challenge-5.0.0.tgz", "integrity": "sha512-ueGLflrrnvwB3xuo/uGob5pd5FN7l0MsLf0Z87o/UQmRtwjvfylfc9MurIxRAWywCYTgrvpXBcqjV4OfCYGCIQ==", + "dev": true, "license": "MIT", "engines": { "node": ">=16.20.0" } }, "node_modules/playwright": { - "version": "1.53.2", - "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.53.2.tgz", - "integrity": "sha512-6K/qQxVFuVQhRQhFsVZ9fGeatxirtrpPgxzBYWyZLEXJzqYwuL4fuNmfOfD5et1tJE4GScKyPNeLhZeRwuTU3A==", + "version": "1.56.1", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.56.1.tgz", + "integrity": "sha512-aFi5B0WovBHTEvpM3DzXTUaeN6eN0qWnTkKx4NQaH4Wvcmc153PdaY2UBdSYKaGYw+UyWXSVyxDUg5DoPEttjw==", "devOptional": true, "license": "Apache-2.0", "dependencies": { - "playwright-core": "1.53.2" + "playwright-core": "1.56.1" }, "bin": { "playwright": "cli.js" @@ -16625,9 +16901,9 @@ } }, "node_modules/playwright-core": { - "version": "1.53.2", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.53.2.tgz", - "integrity": "sha512-ox/OytMy+2w1jcYEYlOo1Hhp8hZkLCximMTUTMBXjGUA1KoFfiSZ+DU+3a739jsPY0yoKH2TFy9S2fsJas8yAw==", + "version": "1.56.1", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.56.1.tgz", + "integrity": "sha512-hutraynyn31F+Bifme+Ps9Vq59hKuUCz7H1kDOcBs+2oGguKkWTU50bBWrtz34OUWmIwpBTWDxaRPXrIXkgvmQ==", "devOptional": true, "license": "Apache-2.0", "bin": { @@ -16845,6 +17121,7 @@ "version": "9.3.0", "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-9.3.0.tgz", "integrity": "sha512-gjVS5hOP+M3wMm5nmNOucbIrqudzs9v/57bWRHQWLYklXqoXKrVfYW2W9+glfGsqtPgpiz5WwyEEB+ksXIx3gQ==", + "dev": true, "license": "MIT", "dependencies": { "parse-ms": "^4.0.0" @@ -16860,6 +17137,7 @@ "version": "2.4.2", "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "dev": true, "license": "MIT", "dependencies": { "kleur": "^3.0.3", @@ -16873,6 +17151,7 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -16903,6 +17182,7 @@ "version": "2.0.7", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dev": true, "license": "MIT", "dependencies": { "forwarded": "0.2.0", @@ -16916,6 +17196,7 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -16925,6 +17206,7 @@ "version": "6.14.0", "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz", "integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==", + "dev": true, "license": "BSD-3-Clause", "dependencies": { "side-channel": "^1.1.0" @@ -16940,6 +17222,7 @@ "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, "funding": [ { "type": "github", @@ -17037,6 +17320,7 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.6" @@ -17046,6 +17330,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.1.tgz", "integrity": "sha512-9G8cA+tuMS75+6G/TzW8OtLzmBDMo8p1JRxN5AZ+LAp8uxGA8V8GZm4GQ4/N5QNQEnLmg6SS7wyuSmbKepiKqA==", + "dev": true, "license": "MIT", "dependencies": { "bytes": "3.1.2", @@ -17061,6 +17346,7 @@ "version": "0.7.0", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.0.tgz", "integrity": "sha512-cf6L2Ds3h57VVmkZe+Pn+5APsT7FpqJtEhhieDCvrE2MK5Qk9MyffgQyuxQTm6BChfeZNtcOLHp9IcWRVcIcBQ==", + "dev": true, "license": "MIT", "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" @@ -17264,6 +17550,7 @@ "version": "0.23.11", "resolved": "https://registry.npmjs.org/recast/-/recast-0.23.11.tgz", "integrity": "sha512-YTUo+Flmw4ZXiWfQKGcwwc11KnoRAYgzAE2E7mXKCjSviTKShtxBsN6YUUBB2gtaBzKzeKunxhUwNHQuRryhWA==", + "dev": true, "license": "MIT", "dependencies": { "ast-types": "^0.16.1", @@ -17424,6 +17711,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -17454,6 +17742,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, "license": "MIT", "engines": { "node": ">=4" @@ -17473,6 +17762,7 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-5.1.0.tgz", "integrity": "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==", + "dev": true, "license": "MIT", "dependencies": { "onetime": "^7.0.0", @@ -17489,6 +17779,7 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/onetime/-/onetime-7.0.0.tgz", "integrity": "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==", + "dev": true, "license": "MIT", "dependencies": { "mimic-function": "^5.0.0" @@ -17513,12 +17804,14 @@ "version": "0.7.0", "resolved": "https://registry.npmjs.org/rettime/-/rettime-0.7.0.tgz", "integrity": "sha512-LPRKoHnLKd/r3dVxcwO7vhCW+orkOGj9ViueosEBK6ie89CijnfRlhaDhHq/3Hxu4CkWQtxwlBG0mzTQY6uQjw==", + "dev": true, "license": "MIT" }, "node_modules/reusify": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "dev": true, "license": "MIT", "engines": { "iojs": ">=1.0.0", @@ -17559,6 +17852,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz", "integrity": "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==", + "dev": true, "license": "MIT", "dependencies": { "debug": "^4.4.0", @@ -17575,6 +17869,7 @@ "version": "8.3.0", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.3.0.tgz", "integrity": "sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==", + "dev": true, "license": "MIT", "funding": { "type": "opencollective", @@ -17595,6 +17890,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, "funding": [ { "type": "github", @@ -17644,6 +17940,7 @@ "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, "funding": [ { "type": "github", @@ -17748,6 +18045,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/send/-/send-1.2.0.tgz", "integrity": "sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw==", + "dev": true, "license": "MIT", "dependencies": { "debug": "^4.3.5", @@ -17770,6 +18068,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.0.tgz", "integrity": "sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ==", + "dev": true, "license": "MIT", "dependencies": { "encodeurl": "^2.0.0", @@ -17840,20 +18139,24 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "dev": true, "license": "ISC" }, "node_modules/shadcn": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/shadcn/-/shadcn-3.2.1.tgz", - "integrity": "sha512-j+yLAXa6CFBz96+O6dtiA+BllDOokYH65eofCYbPY2+NBsFYiSKbyfj6psbujNfng9HP7N9/+j6Uzo2iYxRqtw==", + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/shadcn/-/shadcn-3.4.1.tgz", + "integrity": "sha512-gKLLCGN0lZ9vjbndoGY2cZJKvDtUYGRyF0XoyejHBbCr9lwE6NGlrtRQbA50Wcd/pDdYFyOzT/1wl//HUjSSkw==", + "dev": true, "license": "MIT", "dependencies": { "@antfu/ni": "^25.0.0", "@babel/core": "^7.28.0", "@babel/parser": "^7.28.0", "@babel/plugin-transform-typescript": "^7.28.0", + "@babel/preset-typescript": "^7.27.1", "@dotenvx/dotenvx": "^1.48.4", "@modelcontextprotocol/sdk": "^1.17.2", + "browserslist": "^4.26.2", "commander": "^14.0.0", "cosmiconfig": "^9.0.0", "dedent": "^1.6.0", @@ -17885,6 +18188,7 @@ "version": "14.0.1", "resolved": "https://registry.npmjs.org/commander/-/commander-14.0.1.tgz", "integrity": "sha512-2JkV3gUZUVrbNA+1sjBOYLsMZ5cEEl8GTFP2a4AVz5hvasAMCQ1D2l2le/cX+pV4N6ZU17zjUahLpIXRrnWL8A==", + "dev": true, "license": "MIT", "engines": { "node": ">=20" @@ -17894,6 +18198,7 @@ "version": "9.6.0", "resolved": "https://registry.npmjs.org/execa/-/execa-9.6.0.tgz", "integrity": "sha512-jpWzZ1ZhwUmeWRhS7Qv3mhpOhLfwI+uAX4e5fOcXqwMR7EcJ0pj2kV1CVzHVMX/LphnKWD3LObjZCoJ71lKpHw==", + "dev": true, "license": "MIT", "dependencies": { "@sindresorhus/merge-streams": "^4.0.0", @@ -17920,6 +18225,7 @@ "version": "3.3.3", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "dev": true, "license": "MIT", "dependencies": { "@nodelib/fs.stat": "^2.0.2", @@ -17936,6 +18242,7 @@ "version": "9.0.1", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-9.0.1.tgz", "integrity": "sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==", + "dev": true, "license": "MIT", "dependencies": { "@sec-ant/readable-stream": "^0.4.1", @@ -17952,6 +18259,7 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, "license": "ISC", "dependencies": { "is-glob": "^4.0.1" @@ -17964,6 +18272,7 @@ "version": "8.0.1", "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-8.0.1.tgz", "integrity": "sha512-eKCa6bwnJhvxj14kZk5NCPc6Hb6BdsU9DZcOnmQKSnO1VKrfV0zCvtttPZUsBvjmNDn8rpcJfpwSYnHBjc95MQ==", + "dev": true, "license": "Apache-2.0", "engines": { "node": ">=18.18.0" @@ -17973,6 +18282,7 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-4.0.1.tgz", "integrity": "sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==", + "dev": true, "license": "MIT", "engines": { "node": ">=18" @@ -17985,6 +18295,7 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-6.0.0.tgz", "integrity": "sha512-9qny7Z9DsQU8Ou39ERsPU4OZQlSTP47ShQzuKZ6PRXpYLtIFgl/DEBYEXKlvcEa+9tHVcK8CF81Y2V72qaZhWA==", + "dev": true, "license": "MIT", "dependencies": { "path-key": "^4.0.0", @@ -18001,6 +18312,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "dev": true, "license": "MIT", "engines": { "node": ">=12" @@ -18013,6 +18325,7 @@ "version": "8.5.6", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", + "dev": true, "funding": [ { "type": "opencollective", @@ -18041,6 +18354,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-4.0.0.tgz", "integrity": "sha512-aulFJcD6YK8V1G7iRB5tigAP4TsHBZZrOV8pjV++zdUwmeV8uzbY7yn6h9MswN62adStNZFuCIx4haBnRuMDaw==", + "dev": true, "license": "MIT", "engines": { "node": ">=18" @@ -18053,6 +18367,7 @@ "version": "4.2.0", "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz", "integrity": "sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==", + "dev": true, "license": "MIT", "dependencies": { "json5": "^2.2.2", @@ -18067,6 +18382,7 @@ "version": "3.25.76", "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", + "dev": true, "license": "MIT", "funding": { "url": "https://github.com/sponsors/colinhacks" @@ -18076,6 +18392,7 @@ "version": "3.24.6", "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.24.6.tgz", "integrity": "sha512-h/z3PKvcTcTetyjl1fkj79MHNEjm+HpD6NXheWjzOekY7kV+lwDYnHw+ivHkijnCSMz1yJaWBD9vu/Fcmk+vEg==", + "dev": true, "license": "ISC", "peerDependencies": { "zod": "^3.24.1" @@ -18124,6 +18441,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, "license": "MIT", "dependencies": { "shebang-regex": "^3.0.0" @@ -18136,6 +18454,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -18145,6 +18464,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "dev": true, "license": "MIT", "dependencies": { "es-errors": "^1.3.0", @@ -18164,6 +18484,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "dev": true, "license": "MIT", "dependencies": { "es-errors": "^1.3.0", @@ -18180,6 +18501,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "dev": true, "license": "MIT", "dependencies": { "call-bound": "^1.0.2", @@ -18198,6 +18520,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "dev": true, "license": "MIT", "dependencies": { "call-bound": "^1.0.2", @@ -18217,6 +18540,7 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, "license": "ISC", "engines": { "node": ">=14" @@ -18250,6 +18574,7 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "dev": true, "license": "MIT" }, "node_modules/slash": { @@ -18296,6 +18621,7 @@ "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" @@ -18331,6 +18657,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.8" @@ -18340,6 +18667,7 @@ "version": "0.2.2", "resolved": "https://registry.npmjs.org/stdin-discarder/-/stdin-discarder-0.2.2.tgz", "integrity": "sha512-UhDfHmA92YAlNnCfhmq0VeNL5bDbiZGg7sZ2IvPsXubGkiNa9EC+tUTsjBRsYUAz87btI6/1wf4XoVvQ3uRnmQ==", + "dev": true, "license": "MIT", "engines": { "node": ">=18" @@ -18366,6 +18694,7 @@ "version": "0.5.1", "resolved": "https://registry.npmjs.org/strict-event-emitter/-/strict-event-emitter-0.5.1.tgz", "integrity": "sha512-vMgjE/GGEPEFnhFub6pa4FmJBRBVOLpIII2hvCZ8Kzb7K0hlHo7mQv6xYrBvCL2LtAIBwFUK8wvuJgTVSQ5MFQ==", + "dev": true, "license": "MIT" }, "node_modules/string-argv": { @@ -18382,6 +18711,7 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "dev": true, "license": "MIT", "dependencies": { "emoji-regex": "^10.3.0", @@ -18399,6 +18729,7 @@ "version": "6.2.2", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "dev": true, "license": "MIT", "engines": { "node": ">=12" @@ -18411,12 +18742,14 @@ "version": "10.6.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", + "dev": true, "license": "MIT" }, "node_modules/string-width/node_modules/strip-ansi": { "version": "7.1.2", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", + "dev": true, "license": "MIT", "dependencies": { "ansi-regex": "^6.0.1" @@ -18559,6 +18892,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-5.0.0.tgz", "integrity": "sha512-zaJYxz2FtcMb4f+g60KsRNFOpVMUyuJgA51Zi5Z1DOTC3S59+OQiVOzE9GZt0x72uBGWKsQIuBKeF9iusmKFsg==", + "dev": true, "license": "BSD-2-Clause", "dependencies": { "get-own-enumerable-keys": "^1.0.0", @@ -18576,6 +18910,7 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" @@ -18588,6 +18923,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, "license": "MIT", "engines": { "node": ">=4" @@ -18840,6 +19176,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.0.1.tgz", "integrity": "sha512-5uC6DDlmeqiOwCPmK9jMSdOuZTh8bU39Ys6yidB+UTt5hfZUPGAypSgFRiEp+jbi9qH40BLDvy85jIU88wKSqw==", + "dev": true, "license": "MIT" }, "node_modules/tinyglobby": { @@ -18894,6 +19231,7 @@ "version": "7.0.17", "resolved": "https://registry.npmjs.org/tldts/-/tldts-7.0.17.tgz", "integrity": "sha512-Y1KQBgDd/NUc+LfOtKS6mNsC9CCaH+m2P1RoIZy7RAPo3C3/t8X45+zgut31cRZtZ3xKPjfn3TkGTrctC2TQIQ==", + "dev": true, "license": "MIT", "dependencies": { "tldts-core": "^7.0.17" @@ -18906,12 +19244,14 @@ "version": "7.0.17", "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-7.0.17.tgz", "integrity": "sha512-DieYoGrP78PWKsrXr8MZwtQ7GLCUeLxihtjC1jZsW1DnvSMdKPitJSe8OSYDM2u5H6g3kWJZpePqkp43TfLh0g==", + "dev": true, "license": "MIT" }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, "license": "MIT", "dependencies": { "is-number": "^7.0.0" @@ -18924,6 +19264,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "dev": true, "license": "MIT", "engines": { "node": ">=0.6" @@ -18953,6 +19294,7 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-6.0.0.tgz", "integrity": "sha512-kXuRi1mtaKMrsLUxz3sQYvVl37B0Ns6MzfrtV5DvJceE9bPyspOqk9xxv7XbZWcfLWbFmm997vl83qUWVJA64w==", + "dev": true, "license": "BSD-3-Clause", "dependencies": { "tldts": "^7.0.5" @@ -18998,6 +19340,7 @@ "version": "26.0.0", "resolved": "https://registry.npmjs.org/ts-morph/-/ts-morph-26.0.0.tgz", "integrity": "sha512-ztMO++owQnz8c/gIENcM9XfCEzgoGphTv+nKpYNM1bgsdOVC/jRZuEBf6N+mLLDNg68Kl+GgUZfOySaRiG1/Ug==", + "dev": true, "license": "MIT", "dependencies": { "@ts-morph/common": "~0.27.0", @@ -19036,6 +19379,15 @@ "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", "license": "0BSD" }, + "node_modules/tw-animate-css": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/tw-animate-css/-/tw-animate-css-1.4.0.tgz", + "integrity": "sha512-7bziOlRqH0hJx80h/3mbicLW7o8qLsH5+RaLR2t+OHM3D0JlWGODQKQ4cxbK7WlvmUxpcj6Kgu6EKqjrGFe3QQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/Wombosvideo" + } + }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -19066,6 +19418,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz", "integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==", + "dev": true, "license": "MIT", "dependencies": { "content-type": "^1.0.5", @@ -19158,7 +19511,7 @@ "version": "5.5.4", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz", "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==", - "devOptional": true, + "dev": true, "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", @@ -19191,6 +19544,7 @@ "version": "0.3.0", "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.3.0.tgz", "integrity": "sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==", + "dev": true, "license": "MIT", "engines": { "node": ">=18" @@ -19290,6 +19644,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, "license": "MIT", "engines": { "node": ">= 10.0.0" @@ -19299,6 +19654,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.8" @@ -19343,6 +19699,7 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/until-async/-/until-async-3.0.2.tgz", "integrity": "sha512-IiSk4HlzAMqTUseHHe3VhIGyuFmN90zMTpD3Z3y8jeQbzLIq500MVM7Jq2vUAnTKAFPJrqwkzr6PoTcPhGcOiw==", + "dev": true, "license": "MIT", "funding": { "url": "https://github.com/sponsors/kettanaito" @@ -19352,6 +19709,7 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz", "integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==", + "dev": true, "funding": [ { "type": "opencollective", @@ -19382,6 +19740,7 @@ "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, "license": "BSD-2-Clause", "dependencies": { "punycode": "^2.1.0" @@ -19507,6 +19866,7 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.8" @@ -19566,6 +19926,7 @@ "version": "3.3.3", "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==", + "dev": true, "license": "MIT", "engines": { "node": ">= 8" @@ -19575,6 +19936,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, "license": "ISC", "dependencies": { "isexe": "^2.0.0" @@ -19755,6 +20117,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true, "license": "ISC" }, "node_modules/xml2js": { @@ -19783,6 +20146,7 @@ "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, "license": "ISC", "engines": { "node": ">=10" @@ -19792,6 +20156,7 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true, "license": "ISC" }, "node_modules/yaml": { @@ -19811,6 +20176,7 @@ "version": "17.7.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, "license": "MIT", "dependencies": { "cliui": "^8.0.1", @@ -19829,6 +20195,7 @@ "version": "21.1.1", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, "license": "ISC", "engines": { "node": ">=12" @@ -19838,12 +20205,14 @@ "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, "license": "MIT" }, "node_modules/yargs/node_modules/is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -19853,6 +20222,7 @@ "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", @@ -19880,6 +20250,7 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/yoctocolors/-/yoctocolors-2.1.2.tgz", "integrity": "sha512-CzhO+pFNo8ajLM2d2IW/R93ipy99LWjtwblvC1RsoSUMZgyLbYFr221TnSNT7GjGdYui6P459mw9JH/g/zW2ug==", + "dev": true, "license": "MIT", "engines": { "node": ">=18" @@ -19892,6 +20263,7 @@ "version": "2.1.3", "resolved": "https://registry.npmjs.org/yoctocolors-cjs/-/yoctocolors-cjs-2.1.3.tgz", "integrity": "sha512-U/PBtDf35ff0D8X8D0jfdzHYEPFxAI7jJlxZXwCSez5M3190m+QobIfh+sWDWSHMCWWJN2AWamkegn6vr6YBTw==", + "dev": true, "license": "MIT", "engines": { "node": ">=18" diff --git a/ui/package.json b/ui/package.json index cf2f590feb..ee103a6f45 100644 --- a/ui/package.json +++ b/ui/package.json @@ -15,10 +15,10 @@ "format:check": "./node_modules/.bin/prettier --check ./app", "format:write": "./node_modules/.bin/prettier --config .prettierrc.json --write ./app", "prepare": "husky", - "test:e2e": "playwright test", - "test:e2e:ui": "playwright test --ui", - "test:e2e:debug": "playwright test --debug", - "test:e2e:headed": "playwright test --headed", + "test:e2e": "playwright test --project=chromium", + "test:e2e:ui": "playwright test --project=chromium --ui", + "test:e2e:debug": "playwright test --project=chromium --debug", + "test:e2e:headed": "playwright test --project=chromium --headed", "test:e2e:report": "playwright show-report", "test:e2e:install": "playwright install" }, @@ -70,11 +70,11 @@ "recharts": "2.15.4", "rss-parser": "3.13.0", "server-only": "0.0.1", - "shadcn": "3.2.1", "sharp": "0.33.5", "tailwind-merge": "3.3.1", "tailwindcss-animate": "1.0.7", "topojson-client": "3.1.0", + "tw-animate-css": "1.4.0", "uuid": "11.1.0", "world-atlas": "2.0.2", "zod": "4.1.11", @@ -82,8 +82,8 @@ }, "devDependencies": { "@iconify/react": "5.2.1", - "@playwright/test": "1.53.2", "@types/d3": "7.4.3", + "@playwright/test": "1.56.1", "@types/node": "20.5.7", "@types/react": "19.1.13", "@types/react-dom": "19.1.9", @@ -110,6 +110,7 @@ "postcss": "8.4.38", "prettier": "3.6.2", "prettier-plugin-tailwindcss": "0.6.14", + "shadcn": "3.4.1", "tailwind-variants": "0.1.20", "tailwindcss": "4.1.13", "typescript": "5.5.4" diff --git a/ui/playwright.config.ts b/ui/playwright.config.ts index a680feabdb..5bea00bfe7 100644 --- a/ui/playwright.config.ts +++ b/ui/playwright.config.ts @@ -20,6 +20,72 @@ export default defineConfig({ }, projects: [ + // =========================================== + // Authentication Setup Projects + // =========================================== + // These projects handle user authentication for different permission levels + // Each setup creates authenticated state files that can be reused by test suites + + // Admin user authentication setup + // Creates authenticated state for admin users with full system permissions + { + name: "admin.auth.setup", + testMatch: "admin.auth.setup.ts", + }, + + // Scans management user authentication setup + // Creates authenticated state for users with scan management permissions + { + name: "manage-scans.auth.setup", + testMatch: "manage-scans.auth.setup.ts", + }, + + // Integrations management user authentication setup + // Creates authenticated state for users with integration management permissions + { + name: "manage-integrations.auth.setup", + testMatch: "manage-integrations.auth.setup.ts", + }, + + // Account management user authentication setup + // Creates authenticated state for users with account management permissions + { + name: "manage-account.auth.setup", + testMatch: "manage-account.auth.setup.ts", + }, + + // Cloud providers management user authentication setup + // Creates authenticated state for users with cloud provider management permissions + { + name: "manage-cloud-providers.auth.setup", + testMatch: "manage-cloud-providers.auth.setup.ts", + }, + + // Unlimited visibility user authentication setup + // Creates authenticated state for users with unlimited visibility permissions + { + name: "unlimited-visibility.auth.setup", + testMatch: "unlimited-visibility.auth.setup.ts", + }, + + // Invite and manage users authentication setup + // Creates authenticated state for users with user invitation and management permissions + { + name: "invite-and-manage-users.auth.setup", + testMatch: "invite-and-manage-users.auth.setup.ts", + }, + + // All authentication setups combined + // Runs all authentication setup files to create all user states + { + name: "all.auth.setup", + testMatch: "**/*.auth.setup.ts", + }, + + // =========================================== + // Test Suite Projects + // =========================================== + // These projects run the actual test suites { name: "chromium", use: { ...devices["Desktop Chrome"] }, diff --git a/ui/store/ui/store.ts b/ui/store/ui/store.ts index edc329654f..48bebf22c7 100644 --- a/ui/store/ui/store.ts +++ b/ui/store/ui/store.ts @@ -5,12 +5,15 @@ interface UIStoreState { isSideMenuOpen: boolean; isMutelistModalOpen: boolean; hasProviders: boolean; + shouldAutoOpenMutelist: boolean; openSideMenu: () => void; closeSideMenu: () => void; openMutelistModal: () => void; closeMutelistModal: () => void; setHasProviders: (value: boolean) => void; + requestMutelistModalOpen: () => void; + resetMutelistModalRequest: () => void; } export const useUIStore = create()( @@ -19,11 +22,18 @@ export const useUIStore = create()( isSideMenuOpen: false, isMutelistModalOpen: false, hasProviders: false, + shouldAutoOpenMutelist: false, openSideMenu: () => set({ isSideMenuOpen: true }), closeSideMenu: () => set({ isSideMenuOpen: false }), - openMutelistModal: () => set({ isMutelistModalOpen: true }), + openMutelistModal: () => + set({ + isMutelistModalOpen: true, + shouldAutoOpenMutelist: false, + }), closeMutelistModal: () => set({ isMutelistModalOpen: false }), setHasProviders: (value: boolean) => set({ hasProviders: value }), + requestMutelistModalOpen: () => set({ shouldAutoOpenMutelist: true }), + resetMutelistModalRequest: () => set({ shouldAutoOpenMutelist: false }), }), { name: "ui-store", diff --git a/ui/tests/helpers.ts b/ui/tests/helpers.ts index 9f5efb0fdf..db9c6facbb 100644 --- a/ui/tests/helpers.ts +++ b/ui/tests/helpers.ts @@ -1,4 +1,5 @@ import { Page, expect } from "@playwright/test"; +import { SignInPage, SignInCredentials } from "./page-objects/sign-in-page"; export const ERROR_MESSAGES = { INVALID_CREDENTIALS: "Invalid email or password", @@ -138,6 +139,29 @@ export async function verifyDashboardRoute(page: Page) { await expect(page).toHaveURL("/"); } +export async function authenticateAndSaveState( + page: Page, + email: string, + password: string, + storagePath: string, +) { + if (!email || !password) { + throw new Error('Email and password are required for authentication and save state'); + } + + // Create SignInPage instance + const signInPage = new SignInPage(page); + const credentials: SignInCredentials = { email, password }; + + // Perform authentication steps using Page Object Model + await signInPage.goto(); + await signInPage.login(credentials); + await signInPage.verifySuccessfulLogin(); + + // Save authentication state + await page.context().storageState({ path: storagePath }); +} + export async function getSession(page: Page) { const response = await page.request.get("/api/auth/session"); return response.json(); diff --git a/ui/tests/page-objects/home-page.ts b/ui/tests/page-objects/home-page.ts new file mode 100644 index 0000000000..077591eb4e --- /dev/null +++ b/ui/tests/page-objects/home-page.ts @@ -0,0 +1,125 @@ +import { Page, Locator, expect } from "@playwright/test"; + +export class HomePage { + readonly page: Page; + + // Main content elements + readonly mainContent: Locator; + readonly breadcrumbs: Locator; + readonly overviewHeading: Locator; + + // Navigation elements + readonly navigationMenu: Locator; + readonly userMenu: Locator; + readonly signOutButton: Locator; + + // Dashboard elements + readonly dashboardCards: Locator; + readonly overviewSection: Locator; + + // UI elements + readonly themeToggle: Locator; + readonly logo: Locator; + + constructor(page: Page) { + this.page = page; + + // Main content elements + this.mainContent = page.locator("main"); + this.breadcrumbs = page.getByLabel("Breadcrumbs"); + this.overviewHeading = page.getByRole("heading", { name: "Overview", exact: true }); + + // Navigation elements + this.navigationMenu = page.locator("nav"); + this.userMenu = page.getByRole("button", { name: /user menu/i }); + this.signOutButton = page.getByRole("button", { name: "Sign out" }); + + // Dashboard elements + this.dashboardCards = page.locator('[data-testid="dashboard-card"]'); + this.overviewSection = page.locator('[data-testid="overview-section"]'); + + // UI elements + this.themeToggle = page.getByLabel("Toggle theme"); + this.logo = page.locator('svg[width="300"]'); + } + + // Navigation methods + async goto(): Promise { + await this.page.goto("/"); + await this.waitForPageLoad(); + } + + async waitForPageLoad(): Promise { + await this.page.waitForLoadState("networkidle"); + } + + // Verification methods + async verifyPageLoaded(): Promise { + await expect(this.page).toHaveURL("/"); + await expect(this.mainContent).toBeVisible(); + await expect(this.overviewHeading).toBeVisible(); + await this.waitForPageLoad(); + } + + async verifyBreadcrumbs(): Promise { + await expect(this.breadcrumbs).toBeVisible(); + await expect(this.overviewHeading).toBeVisible(); + } + + async verifyMainContent(): Promise { + await expect(this.mainContent).toBeVisible(); + } + + // Navigation methods + async navigateToOverview(): Promise { + await this.overviewHeading.click(); + } + + async openUserMenu(): Promise { + await this.userMenu.click(); + } + + async signOut(): Promise { + await this.openUserMenu(); + await this.signOutButton.click(); + } + + // Dashboard methods + async verifyDashboardCards(): Promise { + await expect(this.dashboardCards.first()).toBeVisible(); + } + + async verifyOverviewSection(): Promise { + await expect(this.overviewSection).toBeVisible(); + } + + // Utility methods + async refresh(): Promise { + await this.page.reload(); + await this.waitForPageLoad(); + } + + async goBack(): Promise { + await this.page.goBack(); + await this.waitForPageLoad(); + } + + // Accessibility methods + async verifyKeyboardNavigation(): Promise { + // Test tab navigation through main elements + await this.page.keyboard.press("Tab"); + await expect(this.themeToggle).toBeFocused(); + } + + // Wait methods + async waitForRedirect(expectedUrl: string): Promise { + await this.page.waitForURL(expectedUrl); + } + + async waitForContentLoad(): Promise { + await this.page.waitForFunction(() => { + const main = document.querySelector("main"); + return main && main.offsetHeight > 0; + }); + } +} diff --git a/ui/tests/page-objects/sign-in-page.ts b/ui/tests/page-objects/sign-in-page.ts new file mode 100644 index 0000000000..2c426606c7 --- /dev/null +++ b/ui/tests/page-objects/sign-in-page.ts @@ -0,0 +1,316 @@ +import { Page, Locator, expect } from "@playwright/test"; +import { HomePage } from "./home-page"; + +export interface SignInCredentials { + email: string; + password: string; +} + +export interface SocialAuthConfig { + googleEnabled: boolean; + githubEnabled: boolean; +} + +export class SignInPage { + readonly page: Page; + readonly homePage: HomePage; + + // Form elements + readonly emailInput: Locator; + readonly passwordInput: Locator; + readonly loginButton: Locator; + readonly form: Locator; + + // Social authentication buttons + readonly googleButton: Locator; + readonly githubButton: Locator; + readonly samlButton: Locator; + + // Navigation elements + readonly signUpLink: Locator; + readonly backButton: Locator; + + // UI elements + readonly title: Locator; + readonly logo: Locator; + readonly themeToggle: Locator; + + // Error messages + readonly errorMessages: Locator; + readonly loadingIndicator: Locator; + + // SAML specific elements + readonly samlModeTitle: Locator; + readonly samlEmailInput: Locator; + + constructor(page: Page) { + this.page = page; + this.homePage = new HomePage(page); + + // Form elements + this.emailInput = page.getByLabel("Email"); + this.passwordInput = page.getByLabel("Password"); + this.loginButton = page.getByRole("button", { name: "Log in" }); + this.form = page.locator("form"); + + // Social authentication buttons + this.googleButton = page.getByText("Continue with Google"); + this.githubButton = page.getByText("Continue with Github"); + this.samlButton = page.getByText("Continue with SAML SSO"); + + // Navigation elements + this.signUpLink = page.getByRole("link", { name: "Sign up" }); + this.backButton = page.getByText("Back"); + + // UI elements + this.title = page.getByText("Sign in", { exact: true }); + this.logo = page.locator('svg[width="300"]'); + this.themeToggle = page.getByLabel("Toggle theme"); + + // Error messages + this.errorMessages = page.locator('[role="alert"], .error-message, [data-testid="error"]'); + this.loadingIndicator = page.getByText("Loading"); + + // SAML specific elements + this.samlModeTitle = page.getByText("Sign in with SAML SSO"); + this.samlEmailInput = page.getByLabel("Email"); + } + + // Navigation methods + async goto(): Promise { + await this.page.goto("/sign-in"); + await this.waitForPageLoad(); + } + + async waitForPageLoad(): Promise { + await this.page.waitForLoadState("networkidle"); + } + + // Form interaction methods + async fillEmail(email: string): Promise { + await this.emailInput.fill(email); + } + + async fillPassword(password: string): Promise { + await this.passwordInput.fill(password); + } + + async fillCredentials(credentials: SignInCredentials): Promise { + await this.fillEmail(credentials.email); + await this.fillPassword(credentials.password); + } + + async submitForm(): Promise { + await this.loginButton.click(); + } + + async login(credentials: SignInCredentials): Promise { + await this.fillCredentials(credentials); + await this.submitForm(); + } + + // Social authentication methods + async clickGoogleAuth(): Promise { + await this.googleButton.click(); + } + + async clickGithubAuth(): Promise { + await this.githubButton.click(); + } + + async clickSamlAuth(): Promise { + await this.samlButton.click(); + } + + // SAML SSO methods + async toggleSamlMode(): Promise { + await this.clickSamlAuth(); + } + + async goBackFromSaml(): Promise { + await this.backButton.click(); + } + + async fillSamlEmail(email: string): Promise { + await this.samlEmailInput.fill(email); + } + + async submitSamlForm(): Promise { + await this.submitForm(); + } + + // Navigation methods + async goToSignUp(): Promise { + await this.signUpLink.click(); + } + + // Validation and assertion methods + async verifyPageLoaded(): Promise { + await expect(this.page).toHaveTitle(/Prowler/); + await expect(this.logo).toBeVisible(); + await expect(this.title).toBeVisible(); + await this.waitForPageLoad(); + } + + async verifyFormElements(): Promise { + await expect(this.emailInput).toBeVisible(); + await expect(this.passwordInput).toBeVisible(); + await expect(this.loginButton).toBeVisible(); + } + + async verifySocialButtons(config: SocialAuthConfig): Promise { + if (config.googleEnabled) { + await expect(this.googleButton).toBeVisible(); + } + if (config.githubEnabled) { + await expect(this.githubButton).toBeVisible(); + } + await expect(this.samlButton).toBeVisible(); + } + + async verifyNavigationLinks(): Promise { + await expect(this.page.getByText("Need to create an account?")).toBeVisible(); + await expect(this.signUpLink).toBeVisible(); + } + + async verifySuccessfulLogin(): Promise { + await this.homePage.verifyPageLoaded(); + } + + async verifyLoginError(errorMessage: string = "Invalid email or password"): Promise { + await expect(this.page.getByText(errorMessage).first()).toBeVisible(); + await expect(this.page).toHaveURL("/sign-in"); + } + + async verifySamlModeActive(): Promise { + await expect(this.samlModeTitle).toBeVisible(); + await expect(this.passwordInput).not.toBeVisible(); + await expect(this.backButton).toBeVisible(); + } + + async verifyNormalModeActive(): Promise { + await expect(this.title).toBeVisible(); + await expect(this.passwordInput).toBeVisible(); + } + + async verifyLoadingState(): Promise { + await expect(this.loginButton).toHaveAttribute("aria-disabled", "true"); + await expect(this.loadingIndicator).toBeVisible(); + } + + async verifyFormValidation(): Promise { + // Check for common validation messages + const emailError = this.page.getByText("Please enter a valid email address."); + const passwordError = this.page.getByText("Password is required."); + + // At least one validation error should be visible + await expect(emailError.or(passwordError)).toBeVisible(); + } + + // Accessibility methods + async verifyKeyboardNavigation(): Promise { + // Test tab navigation through form elements + await this.page.keyboard.press("Tab"); // Theme toggle + await this.page.keyboard.press("Tab"); // Email field + await expect(this.emailInput).toBeFocused(); + + await this.page.keyboard.press("Tab"); // Password field + await expect(this.passwordInput).toBeFocused(); + + await this.page.keyboard.press("Tab"); // Show password button + await this.page.keyboard.press("Tab"); // Login button + await expect(this.loginButton).toBeFocused(); + } + + async verifyAriaLabels(): Promise { + await expect(this.page.getByRole("textbox", { name: "Email" })).toBeVisible(); + await expect(this.page.getByRole("textbox", { name: "Password" })).toBeVisible(); + await expect(this.page.getByRole("button", { name: "Log in" })).toBeVisible(); + } + + // Utility methods + async clearForm(): Promise { + await this.emailInput.clear(); + await this.passwordInput.clear(); + } + + async isFormValid(): Promise { + const emailValue = await this.emailInput.inputValue(); + const passwordValue = await this.passwordInput.inputValue(); + return emailValue.length > 0 && passwordValue.length > 0; + } + + async getFormErrors(): Promise { + const errorElements = await this.errorMessages.all(); + const errors: string[] = []; + + for (const element of errorElements) { + const text = await element.textContent(); + if (text) { + errors.push(text.trim()); + } + } + + return errors; + } + + // Browser interaction methods + async refresh(): Promise { + await this.page.reload(); + await this.waitForPageLoad(); + } + + async goBack(): Promise { + await this.page.goBack(); + await this.waitForPageLoad(); + } + + // Session management methods + async logout(): Promise { + await this.homePage.signOut(); + } + + async verifyLogoutSuccess(): Promise { + await expect(this.page).toHaveURL("/sign-in"); + await expect(this.title).toBeVisible(); + } + + // Advanced interaction methods + async fillFormWithValidation(credentials: SignInCredentials): Promise { + // Fill email first and check for validation + await this.fillEmail(credentials.email); + await this.page.keyboard.press("Tab"); // Trigger validation + + // Fill password + await this.fillPassword(credentials.password); + } + + async submitFormWithEnterKey(): Promise { + await this.passwordInput.press("Enter"); + } + + async submitFormWithButtonClick(): Promise { + await this.submitForm(); + } + + // Error handling methods + async handleSamlError(): Promise { + const samlError = this.page.getByText("SAML Authentication Error"); + if (await samlError.isVisible()) { + // Handle SAML error if present + console.log("SAML authentication error detected"); + } + } + + // Wait methods + async waitForFormSubmission(): Promise { + await this.page.waitForFunction(() => { + const button = document.querySelector('button[aria-disabled="true"]'); + return button === null; + }); + } + + async waitForRedirect(expectedUrl: string): Promise { + await this.page.waitForURL(expectedUrl); + } +} diff --git a/ui/tests/setups/admin.auth.setup.ts b/ui/tests/setups/admin.auth.setup.ts new file mode 100644 index 0000000000..0e24c242c3 --- /dev/null +++ b/ui/tests/setups/admin.auth.setup.ts @@ -0,0 +1,15 @@ +import { test as authAdminSetup } from '@playwright/test'; +import { authenticateAndSaveState } from '@/tests/helpers'; + +const adminUserFile = 'playwright/.auth/admin_user.json'; + +authAdminSetup('authenticate as admin e2e user', async ({ page }) => { + const adminEmail = process.env.E2E_ADMIN_USER; + const adminPassword = process.env.E2E_ADMIN_PASSWORD; + + if (!adminEmail || !adminPassword) { + throw new Error('E2E_ADMIN_USER and E2E_ADMIN_PASSWORD environment variables are required'); + } + + await authenticateAndSaveState(page, adminEmail, adminPassword, adminUserFile); +}); \ No newline at end of file diff --git a/ui/tests/setups/invite-and-manage-users.auth.setup.ts b/ui/tests/setups/invite-and-manage-users.auth.setup.ts new file mode 100644 index 0000000000..e11eecdaa3 --- /dev/null +++ b/ui/tests/setups/invite-and-manage-users.auth.setup.ts @@ -0,0 +1,15 @@ +import { test as authInviteAndManageUsersSetup } from '@playwright/test'; +import { authenticateAndSaveState } from '@/tests/helpers'; + +const inviteAndManageUsersUserFile = 'playwright/.auth/invite_and_manage_users_user.json'; + +authInviteAndManageUsersSetup('authenticate as invite and manage users e2e user', async ({ page }) => { + const inviteAndManageUsersEmail = process.env.E2E_INVITE_AND_MANAGE_USERS_USER; + const inviteAndManageUsersPassword = process.env.E2E_INVITE_AND_MANAGE_USERS_PASSWORD; + + if (!inviteAndManageUsersEmail || !inviteAndManageUsersPassword) { + throw new Error('E2E_INVITE_AND_MANAGE_USERS_USER and E2E_INVITE_AND_MANAGE_USERS_PASSWORD environment variables are required'); + } + + await authenticateAndSaveState(page, inviteAndManageUsersEmail, inviteAndManageUsersPassword, inviteAndManageUsersUserFile); +}); diff --git a/ui/tests/setups/manage-account.auth.setup.ts b/ui/tests/setups/manage-account.auth.setup.ts new file mode 100644 index 0000000000..4fe5b7b5a2 --- /dev/null +++ b/ui/tests/setups/manage-account.auth.setup.ts @@ -0,0 +1,15 @@ +import { test as authManageAccountSetup } from '@playwright/test'; +import { authenticateAndSaveState } from '@/tests/helpers'; + +const manageAccountUserFile = 'playwright/.auth/manage_account_user.json'; + +authManageAccountSetup('authenticate as manage account e2e user', async ({ page }) => { + const accountEmail = process.env.E2E_MANAGE_ACCOUNT_USER; + const accountPassword = process.env.E2E_MANAGE_ACCOUNT_PASSWORD; + + if (!accountEmail || !accountPassword) { + throw new Error('E2E_MANAGE_ACCOUNT_USER and E2E_MANAGE_ACCOUNT_PASSWORD environment variables are required'); + } + + await authenticateAndSaveState(page, accountEmail, accountPassword, manageAccountUserFile); +}); diff --git a/ui/tests/setups/manage-cloud-providers.auth.setup.ts b/ui/tests/setups/manage-cloud-providers.auth.setup.ts new file mode 100644 index 0000000000..205e2b50e1 --- /dev/null +++ b/ui/tests/setups/manage-cloud-providers.auth.setup.ts @@ -0,0 +1,15 @@ +import { test as authManageCloudProvidersSetup } from '@playwright/test'; +import { authenticateAndSaveState } from '@/tests/helpers'; + +const manageCloudProvidersUserFile = 'playwright/.auth/manage_cloud_providers_user.json'; + +authManageCloudProvidersSetup('authenticate as manage cloud providers e2e user', async ({ page }) => { + const cloudProvidersEmail = process.env.E2E_MANAGE_CLOUD_PROVIDERS_USER; + const cloudProvidersPassword = process.env.E2E_MANAGE_CLOUD_PROVIDERS_PASSWORD; + + if (!cloudProvidersEmail || !cloudProvidersPassword) { + throw new Error('E2E_MANAGE_CLOUD_PROVIDERS_USER and E2E_MANAGE_CLOUD_PROVIDERS_PASSWORD environment variables are required'); + } + + await authenticateAndSaveState(page, cloudProvidersEmail, cloudProvidersPassword, manageCloudProvidersUserFile); +}); diff --git a/ui/tests/setups/manage-integrations.auth.setup.ts b/ui/tests/setups/manage-integrations.auth.setup.ts new file mode 100644 index 0000000000..fb98e4a157 --- /dev/null +++ b/ui/tests/setups/manage-integrations.auth.setup.ts @@ -0,0 +1,15 @@ +import { test as authManageIntegrationsSetup } from '@playwright/test'; +import { authenticateAndSaveState } from '@/tests/helpers'; + +const manageIntegrationsUserFile = 'playwright/.auth/manage_integrations_user.json'; + +authManageIntegrationsSetup('authenticate as integrations e2e user', async ({ page }) => { + const integrationsEmail = process.env.E2E_MANAGE_INTEGRATIONS_USER; + const integrationsPassword = process.env.E2E_MANAGE_INTEGRATIONS_PASSWORD; + + if (!integrationsEmail || !integrationsPassword) { + throw new Error('E2E_MANAGE_INTEGRATIONS_USER and E2E_MANAGE_INTEGRATIONS_PASSWORD environment variables are required'); + } + + await authenticateAndSaveState(page, integrationsEmail, integrationsPassword, manageIntegrationsUserFile); +}); diff --git a/ui/tests/setups/manage-scans.auth.setup.ts b/ui/tests/setups/manage-scans.auth.setup.ts new file mode 100644 index 0000000000..7a8f7e95e2 --- /dev/null +++ b/ui/tests/setups/manage-scans.auth.setup.ts @@ -0,0 +1,15 @@ +import { test as authManageScansSetup } from '@playwright/test'; +import { authenticateAndSaveState } from '@/tests/helpers'; + +const manageScansUserFile = 'playwright/.auth/manage_scans_user.json'; + +authManageScansSetup('authenticate as scans e2e user', async ({ page }) => { + const scansEmail = process.env.E2E_MANAGE_SCANS_USER; + const scansPassword = process.env.E2E_MANAGE_SCANS_PASSWORD; + + if (!scansEmail || !scansPassword) { + throw new Error('E2E_MANAGE_SCANS_USER and E2E_MANAGE_SCANS_PASSWORD environment variables are required'); + } + + await authenticateAndSaveState(page, scansEmail, scansPassword, manageScansUserFile); +}); diff --git a/ui/tests/setups/unlimited-visibility.auth.setup.ts b/ui/tests/setups/unlimited-visibility.auth.setup.ts new file mode 100644 index 0000000000..533158ec70 --- /dev/null +++ b/ui/tests/setups/unlimited-visibility.auth.setup.ts @@ -0,0 +1,15 @@ +import { test as authUnlimitedVisibilitySetup } from '@playwright/test'; +import { authenticateAndSaveState } from '@/tests/helpers'; + +const unlimitedVisibilityUserFile = 'playwright/.auth/unlimited_visibility_user.json'; + +authUnlimitedVisibilitySetup('authenticate as unlimited visibility e2e user', async ({ page }) => { + const unlimitedVisibilityEmail = process.env.E2E_UNLIMITED_VISIBILITY_USER; + const unlimitedVisibilityPassword = process.env.E2E_UNLIMITED_VISIBILITY_PASSWORD; + + if (!unlimitedVisibilityEmail || !unlimitedVisibilityPassword) { + throw new Error('E2E_UNLIMITED_VISIBILITY_USER and E2E_UNLIMITED_VISIBILITY_PASSWORD environment variables are required'); + } + + await authenticateAndSaveState(page, unlimitedVisibilityEmail, unlimitedVisibilityPassword, unlimitedVisibilityUserFile); +}); diff --git a/ui/types/components.ts b/ui/types/components.ts index 98197ea17b..6485f7d0db 100644 --- a/ui/types/components.ts +++ b/ui/types/components.ts @@ -1,5 +1,5 @@ import { LucideIcon } from "lucide-react"; -import { SVGProps } from "react"; +import { MouseEvent, SVGProps } from "react"; import { ProviderCredentialFields } from "@/lib/provider-credentials/provider-credential-fields"; @@ -21,7 +21,7 @@ export type SubmenuProps = { active?: boolean; icon: IconComponent; disabled?: boolean; - onClick?: () => void; + onClick?: (event: MouseEvent) => void; }; export type MenuProps = { @@ -213,15 +213,24 @@ export type AzureCredentials = { [ProviderCredentialFields.PROVIDER_ID]: string; }; -export type M365Credentials = { +export type M365ClientSecretCredentials = { [ProviderCredentialFields.CLIENT_ID]: string; [ProviderCredentialFields.CLIENT_SECRET]: string; [ProviderCredentialFields.TENANT_ID]: string; - [ProviderCredentialFields.USER]?: string; - [ProviderCredentialFields.PASSWORD]?: string; [ProviderCredentialFields.PROVIDER_ID]: string; }; +export type M365CertificateCredentials = { + [ProviderCredentialFields.CLIENT_ID]: string; + [ProviderCredentialFields.CERTIFICATE_CONTENT]: string; + [ProviderCredentialFields.TENANT_ID]: string; + [ProviderCredentialFields.PROVIDER_ID]: string; +}; + +export type M365Credentials = + | M365ClientSecretCredentials + | M365CertificateCredentials; + export type GCPDefaultCredentials = { client_id: string; client_secret: string; diff --git a/ui/types/formSchemas.ts b/ui/types/formSchemas.ts index 10900a3f26..d6421ee16d 100644 --- a/ui/types/formSchemas.ts +++ b/ui/types/formSchemas.ts @@ -168,12 +168,13 @@ export const addCredentialsFormSchema = ( .min(1, "Client ID is required"), [ProviderCredentialFields.CLIENT_SECRET]: z .string() - .min(1, "Client Secret is required"), + .optional(), + [ProviderCredentialFields.CERTIFICATE_CONTENT]: z + .string() + .optional(), [ProviderCredentialFields.TENANT_ID]: z .string() .min(1, "Tenant ID is required"), - [ProviderCredentialFields.USER]: z.string().optional(), - [ProviderCredentialFields.PASSWORD]: z.string().optional(), } : providerType === "github" ? { @@ -194,23 +195,26 @@ export const addCredentialsFormSchema = ( }) .superRefine((data: Record, ctx) => { if (providerType === "m365") { - const hasUser = !!data[ProviderCredentialFields.USER]; - const hasPassword = !!data[ProviderCredentialFields.PASSWORD]; - - if (hasUser && !hasPassword) { - ctx.addIssue({ - code: z.ZodIssueCode.custom, - message: "If you provide a user, you must also provide a password", - path: [ProviderCredentialFields.PASSWORD], - }); - } - - if (hasPassword && !hasUser) { - ctx.addIssue({ - code: z.ZodIssueCode.custom, - message: "If you provide a password, you must also provide a user", - path: [ProviderCredentialFields.USER], - }); + // Validate based on the via parameter + if (via === "app_client_secret") { + const clientSecret = data[ProviderCredentialFields.CLIENT_SECRET]; + if (!clientSecret || clientSecret.trim() === "") { + ctx.addIssue({ + code: "custom", + message: "Client Secret is required", + path: [ProviderCredentialFields.CLIENT_SECRET], + }); + } + } else if (via === "app_certificate") { + const certificateContent = + data[ProviderCredentialFields.CERTIFICATE_CONTENT]; + if (!certificateContent || certificateContent.trim() === "") { + ctx.addIssue({ + code: "custom", + message: "Certificate Content is required", + path: [ProviderCredentialFields.CERTIFICATE_CONTENT], + }); + } } } @@ -219,7 +223,7 @@ export const addCredentialsFormSchema = ( if (via === "personal_access_token") { if (!data[ProviderCredentialFields.PERSONAL_ACCESS_TOKEN]) { ctx.addIssue({ - code: z.ZodIssueCode.custom, + code: "custom", message: "Personal Access Token is required", path: [ProviderCredentialFields.PERSONAL_ACCESS_TOKEN], }); @@ -227,7 +231,7 @@ export const addCredentialsFormSchema = ( } else if (via === "oauth_app") { if (!data[ProviderCredentialFields.OAUTH_APP_TOKEN]) { ctx.addIssue({ - code: z.ZodIssueCode.custom, + code: "custom", message: "OAuth App Token is required", path: [ProviderCredentialFields.OAUTH_APP_TOKEN], }); @@ -235,14 +239,14 @@ export const addCredentialsFormSchema = ( } else if (via === "github_app") { if (!data[ProviderCredentialFields.GITHUB_APP_ID]) { ctx.addIssue({ - code: z.ZodIssueCode.custom, + code: "custom", message: "GitHub App ID is required", path: [ProviderCredentialFields.GITHUB_APP_ID], }); } if (!data[ProviderCredentialFields.GITHUB_APP_KEY]) { ctx.addIssue({ - code: z.ZodIssueCode.custom, + code: "custom", message: "GitHub App Private Key is required", path: [ProviderCredentialFields.GITHUB_APP_KEY], }); @@ -390,7 +394,7 @@ export const mutedFindingsConfigFormSchema = z.object({ const yamlValidation = validateYaml(val); if (!yamlValidation.isValid) { ctx.addIssue({ - code: z.ZodIssueCode.custom, + code: "custom", message: `Invalid YAML format: ${yamlValidation.error}`, }); return; @@ -399,7 +403,7 @@ export const mutedFindingsConfigFormSchema = z.object({ const mutelistValidation = validateMutelistYaml(val); if (!mutelistValidation.isValid) { ctx.addIssue({ - code: z.ZodIssueCode.custom, + code: "custom", message: `Invalid mutelist structure: ${mutelistValidation.error}`, }); } diff --git a/util/compliance/ccc/from_yaml_to_json.py b/util/compliance/ccc/from_yaml_to_json.py new file mode 100644 index 0000000000..d19156d09b --- /dev/null +++ b/util/compliance/ccc/from_yaml_to_json.py @@ -0,0 +1,159 @@ +""" +Script to convert CCC security controls YAML files to JSON format. +""" + +import json +import sys +from pathlib import Path + +import yaml + + +def load_yaml(file_path): + """Load YAML file.""" + try: + with open(file_path, "r", encoding="utf-8") as file: + return yaml.safe_load(file) + except Exception as e: + print(f"Error loading YAML file: {e}") + return None + + +def transform_yaml_to_json(yaml_data): + """Transform YAML structure to JSON.""" + + result = { + "Framework": "CCC", + "Version": "", + "Provider": "", + "Description": "The best practices for Common Cloud Controls Catalog (CCC) for ", + "Requirements": [], + } + + control_families = yaml_data.get("control-families", []) + + for family in control_families: + family_name = family.get("title", "") + family_description = family.get("description", "") + controls = family.get("controls", []) + + for control in controls: + control_id = control.get("id", "") + control_title = control.get("title", "") + control_objective = control.get("objective", "") + + threat_mappings = control.get("threat-mappings", []) + guideline_mappings = control.get("guideline-mappings", []) + + assessment_reqs = control.get("assessment-requirements", []) + + for req in assessment_reqs: + req_id = req.get("id", "") + req_text = req.get("text", "").strip() + applicability = req.get("applicability", []) + recommendation = req.get("recommendation", "") + + section_threat_mappings = [] + for tm in threat_mappings: + ref_id = tm.get("reference-id", "") + entries = tm.get("entries", []) + identifiers = [] + for entry in entries: + entry_ref = entry.get("reference-id", "") + if entry_ref: + if "Core." in entry_ref: + entry_ref = entry_ref.replace("Core.", "") + identifiers.append(entry_ref) + + if identifiers: + section_threat_mappings.append( + {"ReferenceId": ref_id, "Identifiers": identifiers} + ) + + section_guideline_mappings = [] + for gm in guideline_mappings: + ref_id = gm.get("reference-id", "") + entries = gm.get("entries", []) + identifiers = [] + for entry in entries: + entry_ref = entry.get("reference-id", "") + if entry_ref: + identifiers.append(entry_ref) + + if identifiers: + section_guideline_mappings.append( + {"ReferenceId": ref_id, "Identifiers": identifiers} + ) + + checks = [] + + requirement = { + "Id": req_id, + "Description": req_text, + "Attributes": [ + { + "FamilyName": family_name, + "FamilyDescription": family_description, + "Section": f"{control_id} {control_title}", + "SubSection": "", + "SubSectionObjective": control_objective.strip(), + "Applicability": applicability, + "Recommendation": recommendation, + "SectionThreatMappings": section_threat_mappings, + "SectionGuidelineMappings": section_guideline_mappings, + } + ], + "Checks": checks, + } + + result["Requirements"].append(requirement) + + return result + + +def save_json(data, file_path): + """Save data as JSON.""" + try: + with open(file_path, "w", encoding="utf-8") as file: + json.dump(data, file, indent=2, ensure_ascii=False) + return True + except Exception as e: + print(f"Error saving JSON file: {e}") + return False + + +def main(): + """Main function.""" + if len(sys.argv) < 2: + print("Usage: python from_yaml_to_json.py [output_file.json]") + sys.exit(1) + + input_file = sys.argv[1] + output_file = sys.argv[2] if len(sys.argv) > 2 else "output.json" + + if not Path(input_file).exists(): + print(f"Error: File {input_file} does not exist.") + sys.exit(1) + + print(f"Loading {input_file}...") + yaml_data = load_yaml(input_file) + + if yaml_data is None: + print("Could not load YAML file.") + sys.exit(1) + + print("Transforming YAML to JSON...") + json_data = transform_yaml_to_json(yaml_data) + + print(f"Saving result to {output_file}...") + if save_json(json_data, output_file): + print("Conversion completed successfully!") + print(f"Generated file: {output_file}") + print(f"Total requirements processed: {len(json_data['Requirements'])}") + else: + print("Error saving JSON file.") + sys.exit(1) + + +if __name__ == "__main__": + main()